我正在练习通过点击Jbutton在JPanel上绘制一个形状,但我不能。我正在网上冲浪五个小时,但我找不到办法。 这就是我想要做的:如果我点击“矩形”按钮,按钮下会出现一个矩形,如果我点击“圆圈”按钮,就会出现一个圆圈。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Shape extends JFrame {
JButton rec, circle;
static String botSelected;
Shape (){
frameSet ();
}
void frameSet(){
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(600,300);
rec = new JButton ("Rectangle");
circle = new JButton("Circle");
JPanel panel = new JPanel();
frame.add(panel);
panel.add(rec);
panel.add(circle);
Click clk = new Click();
rec.addActionListener(clk);
circle.addActionListener(clk);
}
public void paint (Graphics g){
super.paint(g);
if (botSelected.equals("Rectangle"))
g.fillRect(50,50,50,50);
else if (botSelected.equals("Circle"))
g.fillOval(50,50,50,50);
}
public static void main (String [] arg){
Shape s = new Shape();
}
}
class Click implements ActionListener{
public void actionPerformed (ActionEvent e){
Shape.botSelected = e.getActionCommand();
}
}
答案 0 :(得分:1)
我要做的第一件事是阅读Painting in Swing和Performing custom painting,以便更好地了解绘画过程的工作原理。
接下来你需要明白JFrame
是绘画的不错选择。为什么?因为它是多层次的。
JFrame
包含JRootPane
,其中包含JLayeredPane
contentPane
,glassPane
和JMenuBar
,在您的示例中,还包含JPanel
。
使用glassPane
的(默认)例外,所有这些组件都是不透明的。
虽然可以在paint
方法中绘制一些东西来展示它,但是如果任何其他组件自己绘制,它将被擦干净 - 这是因为Swing组件实际上可以独立绘制彼此必须先让父母自己画画。
更好的解决方案是从JPanel
延伸并覆盖其paintComponent
方法。
为简单起见,我还鼓励您对此类实施ActionListener
,它将允许actionPerformed
方法访问组件的属性,在您的情况下,当您想要更新UI时,调用repaint
来触发绘制周期。
答案 1 :(得分:1)
以下是您的代码中的派生示例。
正如@MadProgrammer所说,不要延长JFrame
。
在以下示例中,以下是主要更改:
为botSelected
提供非空值,或者第一次拨打paintComponent
会给您NullPointerException
该课程现在扩展JPanel
,并覆盖paintComponent
以进行自定义绘画
ActionListener
是一个匿名类,因为您不需要单独的类,并且可以直接访问Shape
botSelected
不再是静态的(参见上文)
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
class Shape extends JPanel {
JButton rec, circle;
String botSelected = "";// don't let it be null, it would make paintComponent crash on startup
Shape() {
frameSet();
}
void frameSet() {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(600, 300);
rec = new JButton("Rectangle");
circle = new JButton("Circle");
frame.add(this);
this.add(rec);
this.add(circle);
// anonymous class, has access to fields from the outer class Shape
ActionListener clk = new ActionListener() {
public void actionPerformed(final ActionEvent e) {
botSelected = e.getActionCommand();
repaint();
}
};
rec.addActionListener(clk);
circle.addActionListener(clk);
}
//custom painting of the JPanel
@Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
if (botSelected.equals("Rectangle")) {
g.fillRect(50, 50, 50, 50);
} else if (botSelected.equals("Circle")) {
g.fillOval(50, 50, 50, 50);
}
}
public static void main(final String[] arg) {
Shape s = new Shape();
}
}