Java Swing应用程序 - 如果resizable设置为false,则不会出现按钮

时间:2010-11-26 16:52:56

标签: java swing

我有以下代码。 KochSnowflakesMenu类是一个带有三个按钮的网格JPanel。 KochSnowflakesDraw类目前使用drawOval绘制一个圆圈:

import javax.swing.*;
import java.awt.*;

public class KochSnowflakes
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("Koch Snowflakes");
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(0,0, 600, 425);
        frame.setBackground(Color.BLACK);
        frame.setResizable(false);
        frame.setLayout(null);

        // Create the button interface
        frame.add(new KochSnowflakesMenu());
        frame.add(new KochSnowflakesDraw());
        frame.repaint();
    }
}

如果我注释掉frame.setResizable(false),这是有效的。当我不这样做时,按钮不会出现。这是为什么?如您所见,我尝试使用repaint()。我之前遇到的问题是,在手动调整窗口大小之前按钮不会显示...

另外,作为一个额外的问题,如果有人能告诉我如何获得一个很棒的JPanel尺寸。我之所以无法使用像BorderLayout这样的可调整大小的布局管理器,实际上是我想要使用的,是因为我无法弄清楚占据中心的JPanel的维度(因此不知道如何很大,我正在绘制的东西。

编辑: 根据要求,这是KockSnowflakesMenu类:

import javax.swing.*;
import java.awt.*;

public class KochSnowflakesMenu extends JPanel
{
    public KochSnowflakesMenu()
    {
        setLayout(new GridLayout(3,1));
        setBounds(0,0,200,400);

        JButton button_red = new JButton("Red");
        JButton button_yellow = new JButton("Yellow");
        JButton button_blue = new JButton("Blue");

        add(button_red);
        add(button_yellow);
        add(button_blue);
    }
}

而且,为了确保我没有弄乱KochSnowflakesDraw的东西,这里也是那个类:

import javax.swing.*;
import java.awt.*;

public class KochSnowflakesDraw extends JPanel
{
    public KochSnowflakesDraw()
    {
        setLayout(null);
        setBounds(200, 0, 400, 400);
    }

    public void paintComponent(Graphics g)
    {
        g.setColor(Color.RED);
        g.drawOval(0,0,400, 400);
    }
}

4 个答案:

答案 0 :(得分:1)

一般来说,使用JFrame时,您应该使用contentPane而不是JFrame本身,所以要添加项目,请尝试

frame.getContentPane().add(.....);

关于第一个问题,请尝试在JFrame上使用pack。 http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Window.html#pack()

对于你的奖金问题,JComponent有一个getWidth和getHeight方法。这将告诉您JPanel的当前大小。

http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/JComponent.html#getWidth()

答案 1 :(得分:0)

为以前的答案添加更多信息... 在绘制组件之前,大小是随机的,因此请确保框架上有setVisible(true)。这是你的代码w /一些修改,让你使用BorderLayout并获得绘图面板的大小。我为你的界面替换了一些假按钮,但你会得到漂移。


JFrame frame = new JFrame("Koch Snowflakes");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0,0, 600, 425);
frame.setBackground(Color.BLACK);
frame.setResizable(false);
frame.setLayout(new BorderLayout());

JPanel buttons = new JPanel(new FlowLayout());
buttons.add(new JButton("MENU"));
buttons.add(new JButton("DRAW"));
frame.add(buttons, BorderLayout.SOUTH);

JPanel drawArea = new JPanel();
drawArea.setBackground(Color.BLUE);
frame.add(drawArea, BorderLayout.CENTER);
frame.setVisible(true);
Dimension drawAreaDim = drawArea.getSize();
System.out.println(drawAreaDim);

答案 2 :(得分:0)

将组件添加到可见帧时,代码应为:

panel.add(...);
panel.revalidate();
panel.repaint(); // sometimes required

答案 3 :(得分:0)

确保在Event Dispatch Thread(EDT)上创建Swing对象。在你的例子中,你不是,当你得到奇怪的,不一致的行为时,这通常是候选人。 Swing不是线程安全的,并且依赖于在EDT上创建和修改Swing对象。

要解决此问题,只需将main方法的内容包装在SwingUtilities.invokeLater调用中,如下所示:

public static void main(String[] args)
{
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run()
        {
            JFrame frame = new JFrame("Koch Snowflakes");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setBounds(0,0, 600, 425);
            frame.setBackground(Color.BLACK);
            frame.setResizable(false);
            frame.setLayout(null);

            // Create the button interface
            frame.add(new KochSnowflakesMenu());
            frame.add(new KochSnowflakesDraw());
            frame.setVisible(true);
        }
    });
}

这将在EDT线程上创建您的JFrame和其他组件。这是否解决了不一致的“它在大多数情况下不起作用”的行为?

另外,我更喜欢最后调用setVisible ...虽然它可能无关紧要。