我正在尝试做一个简单的作业,在那里我显示一行文字,显示门对象是否打开。在其下面,我直观地表示它(使用drawRect)方法。在底部我有两个按钮,可以打开或关闭门,从而改变文本和矩形。
编辑:现在可以编译的代码列表:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
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;
import javax.swing.JTextField;
public class Test {
public static void main(String[] args) {
// Creates new JFrame called frame, with title "Door"
// (displayed at top of screen).
JFrame frame = new JFrame ("Door");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TempDoorPanel panel = new TempDoorPanel();
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
class Door {
private String state;
private String message;
Door (String state) {
this.state = state;
message = "The door is currently closed.";
}
public boolean isOpen() {
return state.equals ("open");
}
public boolean isClosed() {
return state.equals ("closed");
}
public void setState(String state) {
this.state = state;
}
public String getMessage() {
return message;
}
public void open() {
if (state.equals("open")) {
message = "The door is already open.";
}
else {
state = "open";
message = "The door has been opened.";
}
}
public void drawOpenDoor (Graphics page) {
page.drawRect(100, 100, 100, 100);
}
}
class TempDoorPanel extends JPanel {
private Door door;
private JTextField currentStateOfDoor;
private JButton openDoor;
public TempDoorPanel() {
super.setLayout(new BorderLayout());
door = new Door("closed");
super.setBackground(Color.blue);
super.setPreferredSize(new Dimension (360, 400));
currentStateOfDoor = new JTextField(14);
currentStateOfDoor.setText(door.getMessage());
super.add(currentStateOfDoor, BorderLayout.NORTH);
openDoor = new JButton("Open Door");
class openDoorListener implements ActionListener {
public void actionPerformed (ActionEvent event) {
door.open();
repaintText();
}
}
openDoorListener openlistener = new openDoorListener();
openDoor.addActionListener(openlistener);
JPanel holder = new JPanel();
holder.add(openDoor);
super.add(holder, BorderLayout.SOUTH);
}
private void repaintText() {
currentStateOfDoor.setText(door.getMessage());
// These methods are from Door class.
}
public void paintComponent (Graphics page) {
super.paintComponent(page);
if (door.isOpen())
door.drawOpenDoor(page);
// isOpen is a boolean method from Door class.
}
}
什么有效:
我正在努力解决的问题:
问题:
答案 0 :(得分:4)
因为您向JPanel添加组件,所以您在JTextField
上绘制的内容将覆盖您的绘图。
<强>解决方案:强>
1)通过检查JTextField
方法中的drawRect(..)
高度来补偿这一点
或更好
2)除非无法帮助,否则不要将组件添加到您正在绘制的同一JPanel
。
所以基本上我让你的TempDoorPanel
添加了一个新的JPanel
到BorderLayout.CENTER
这是绘图面板我们现在可以使用drawRect(0,0,10,10)
了将显示在JPanel
drawingPanel
的左上角。
也不要在setPreferredSize
上致电JPanel
,而是覆盖getPreferredSize()
并返回符合您图纸的Dimension
。
要在课堂外调用paintComponent
,只需致电repaint()
其实例
请参阅使用第2点的示例:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
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;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Door");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
TempDoorPanel panel = new TempDoorPanel();
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
});
}
}
class Door {
private String state;
private String message;
public Door(String state) {
this.state = state;
message = "The door is currently closed.";
}
public void drawOpenDoor(Graphics page) {
page.setColor(Color.GREEN);
page.drawRect(0, 0, 10, 10);
}
}
class TempDoorPanel extends JPanel {
private Door door;
private JTextField currentStateOfDoor;
private JButton openDoor;
public TempDoorPanel() {
super.setLayout(new BorderLayout());
door = new Door("closed");
currentStateOfDoor = new JTextField(14);
//AcurrentStateOfDoor.setText(door.getMessage());
super.add(currentStateOfDoor, BorderLayout.NORTH);
openDoor = new JButton("Open Door");
final JPanel drawingPanel = new JPanel() {
@Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
// if (door.isOpen()) {
door.drawOpenDoor(grphcs);
// }
// isOpen is a boolean method from Door class.
}
};
drawingPanel.setBackground(Color.blue);
add(drawingPanel);
class openDoorListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
//door.open();
repaintText();
drawingPanel.repaint();//so paint component of drawing panel is called
}
}
openDoorListener openlistener = new openDoorListener();
openDoor.addActionListener(openlistener);
JPanel holder = new JPanel();
holder.add(openDoor);
super.add(holder, BorderLayout.SOUTH);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
private void repaintText() {
// currentStateOfDoor.setText(door.getMessage());
// These methods are from Door class.
}
}
答案 1 :(得分:3)
当您与听众处理开门事件时;
class openDoorListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
door.open();
repaintText();
}
}
您实际上并未包含重新绘制面板的电话;因此,不会调用面板的paintComponent()
方法,也不会调用door.drawOpenDoor()
。您可以通过单击按钮然后调整框架大小来测试它。当您调整大小时,面板会自动重新绘制并且宾果游戏,您的门会出现。
您可以通过在ActionListener中添加对repaint()
的调用来解决此问题;
class openDoorListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
door.open();
repaintText();
repaint(); // requests that the panel be repainted
}
}