我有以下代码。 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);
}
}
答案 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 ...虽然它可能无关紧要。