Java 将图形添加到面板
这应该足够简单,但我不能让它工作 我有两个类,一个应该画一个圆,另一个设置一个框架和一个按钮面板。单击按钮时,框架上会出现一个圆圈。我不明白为什么它没有出现。很可能很简单,对不起Java 将图形添加到面板,java,jpanel,graphics2d,Java,Jpanel,Graphics2d,这应该足够简单,但我不能让它工作 我有两个类,一个应该画一个圆,另一个设置一个框架和一个按钮面板。单击按钮时,框架上会出现一个圆圈。我不明白为什么它没有出现。很可能很简单,对不起 package ballsOnPane; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import
package ballsOnPane;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Display implements ActionListener{
private JFrame frame;
private JPanel panel;
private JButton button;
public static void main(String[] args) {
Display display = new Display();
}
public Display() {
frame = new JFrame();
frame.setSize(800, 500);
frame.setTitle("Show balls");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
panel = new JPanel();
frame.add(panel, BorderLayout.CENTER);
button = new JButton("New Ball");
frame.add(button, BorderLayout.SOUTH);
button.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
Ball ball = new Ball(100, 100, 50);
panel.add(ball);
}
}
和球类:
package ballsOnPane;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;
public class Ball extends JPanel{
private int x;
private int y;
private int r;
public Ball(int x, int y, int r){
this.x = x;
this.y = y;
this.r = r;
}
public void paintComponent(Graphics g) {
Graphics2D g2 =(Graphics2D) g;
Ellipse2D circ = new Ellipse2D.Float(x, y, r, r);
g2.draw(circ);
}
}
将组件添加到可见GUI时,基本代码为:
panel.add(...);
panel.revalidate(); // to invoke the layout manager
panel.repaint(); // to repaint the components
否则,添加的组件的大小为(0,0),因此没有要绘制的内容。按钮也是如此。应该在框架可见之前添加它,或者您还需要执行revalidate()/repaint()
在这种情况下,您还有第二个问题:
frame.add(panel, BorderLayout.CENTER);
首先将空面板添加到BorderLayout的中心,然后单击按钮将球添加到中心
Swing将首先绘制最后添加的组件。所以球被涂上油漆,然后空面板被涂到顶部
把面板拿开,它没用
编辑:
出于某种原因,我以为您在单击按钮时将球添加到框架而不是面板
我上面的解释是正确的,如果你确实把球直接添加到框架中
但是,我的解释是不正确的,因为ActionListener中的代码确实将球添加到了面板中。正确的解释如下
将球添加到面板时,不会看到球,因为默认情况下,JPanel使用FlowLayout,并且FlowLayout尊重添加到其中的任何组件的首选大小。您没有实现getPreferredSize()
方法,因此大小为(0,0),因此没有任何可绘制的内容
因此,如果您在Ball类中实现了
getPreferredSize()
方法,则球将显示在面板上。此外,每次单击按钮时,您都可以显示一个新球。正如camickr回答的那样,您需要重新验证()
(或者调用这两个无效()
和验证()
,两者都可以工作),然后重新绘制()
面板
失效方法将面板标记为“不正确”;基本上是做标记检查
验证执行组件的布局
重新验证日期同时执行这两项操作,但是,验证是同步的,而重新验证日期不是同步的
验证面板后,需要调用repaint重新绘制该面板
作为旁注,在我看来,它更容易使用。你可能想调查一下。:) 一个简短的代码示例,用于在JavaFX中执行类似于您当前正在执行的操作:
public class test extends Application{
Scene scene;
@Override
public void start(Stage primaryStage) throws Exception{
StackPane root = new StackPane();
root.setBackground(
new Background(new BackgroundFill(Color.ALICEBLUE,null,null)));
Button begin = new Button("Add Circle");
begin.setOnAction((ActionEvent e)->{
Circle c = new Circle(200,200,100,Color.RED);
root.getChildren().add(c);
});
root.getChildren().add(begin);
scene = new Scene(root, 700, 700);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
你至少看不到其中一个圆圈吗?不,我制作了其他类似的程序,在这些程序中我成功地在面板上获取了图像,并且我尝试了使用相同的格式,但没有显示任何内容。LuxxMiner也谢谢你,这有助于:)谢谢!现在这很有道理。并修复了许多其他与Java相关的问题)不,不,不。。。保留面板。你真的不应该在画框上画画。代码是正确的-它将球添加到面板,而不是框架。但球没有指定首选大小,因此默认为零。此外,所有这些都没有在事件线程上执行,因此GUI不会正确显示。@FredK,在我的建议中,他不会将
Ball
面板添加到框架的内容窗格中,这非常好。框架的内容窗格是一个JPanel,不需要创建第二个面板。@Ash,正如FredK指出的那样,Ball类不会覆盖getPreferredSize()
方法,只会显示,因为您使用的是BorderLayout。要正确绘制,请阅读上Swing教程中的部分,以获得更好的工作示例。