下面是我绘制游泳池的代码,同时计算其体积。
有问题的方法是paintSwimmingPool(),它在stateChanged()监听器方法调用时工作正常。但是,问题是我想在启动程序时绘制矩形。我在一些控制台消息中添加了帮助调试,它告诉我从createGUI()方法正确调用该方法。但为什么paintSwimmingPool()不会在面板上绘制任何东西?对不起,我花了很多时间来解决这个问题,但没有找到。
提前感谢您的任何指示。
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class SwimingPoolCalculator implements ChangeListener {
private JFrame frame;
private JPanel primaryJPanel, drawingJPanel;
private JLabel deepJLabel, shallowJLabel;
private JSlider deepJSlider, shallJSlider;
private JTextField resultTextField;
final private int xPos = 20;
final private int yPos = 20;
final private int swimmingPoolLength = 200;
final private int swimmingPoolWidth = 50;
public static void main(String[] args) {
SwimingPoolCalculator swimingPoolCalculator = new SwimingPoolCalculator();
swimingPoolCalculator.createGUI();
}
private void createGUI(){
frame = new JFrame("Swiming Pool Calculator");
primaryJPanel = new JPanel();
primaryJPanel.setPreferredSize(new Dimension(250, 500));
drawingJPanel = new JPanel();
drawingJPanel.setPreferredSize(new Dimension(250, 300));
drawingJPanel.setBackground(Color.yellow);
shallowJLabel = new JLabel("S End");
deepJLabel = new JLabel("D End");
shallJSlider = new JSlider(JSlider.HORIZONTAL, 10, 100, 10);
deepJSlider = new JSlider(JSlider.HORIZONTAL, 50, 200, 100);
shallJSlider.addChangeListener(this);
deepJSlider.addChangeListener(this);
resultTextField = new JTextField(15);
primaryJPanel.add(drawingJPanel);
primaryJPanel.add(shallowJLabel);
primaryJPanel.add(shallJSlider);
primaryJPanel.add(deepJLabel);
primaryJPanel.add(deepJSlider);
primaryJPanel.add(resultTextField);
frame.getContentPane().add(primaryJPanel);
frame.pack();
frame.setVisible(true);
// why the first call does not draw any line?
paintSwimmingPool(deepJSlider.getValue(), shallJSlider.getValue());
}
private void paintSwimmingPool(int deepEnd, int shallowEnd){
Graphics drawingBoard = drawingJPanel.getGraphics();
drawingBoard.setColor(Color.yellow);
drawingBoard.fillRect(0, 0, 250, 250);
drawingBoard.setColor(Color.black);
drawingBoard.drawLine(xPos, yPos, xPos + swimmingPoolLength, yPos); // the top line
drawingBoard.drawLine(xPos, yPos, xPos, yPos + deepEnd); // the left line
drawingBoard.drawLine(xPos + swimmingPoolLength, yPos, xPos + swimmingPoolLength, yPos + shallowEnd); // the right line
drawingBoard.drawLine(xPos, yPos + deepEnd, xPos + swimmingPoolLength, yPos + shallowEnd); // the bottom line
}
private void calculateVolume(double averageDepth){
int swimmingPoolVolume = (int)(averageDepth * swimmingPoolLength * swimmingPoolWidth);
resultTextField.setText("Volume: " + swimmingPoolVolume);
}
@Override
public void stateChanged(ChangeEvent e) {
int shallowEnd = shallJSlider.getValue();
int deepEnd = deepJSlider.getValue();
double averageDepth = (shallowEnd + deepEnd) / 2;
paintSwimmingPool(deepEnd, shallowEnd);
calculateVolume(averageDepth);
}
}
答案 0 :(得分:3)
你不能这样绘制,正确的技术是
完全成功的例子
public class SwimingPoolCalculator implements ChangeListener {
private JFrame frame;
private JPanel primaryJPanel, drawingJPanel;
private JLabel deepJLabel, shallowJLabel;
private JSlider deepJSlider, shallJSlider;
private JTextField resultTextField;
final private int xPos = 20;
final private int yPos = 20;
final private int swimmingPoolLength = 200;
final private int swimmingPoolWidth = 50;
private int deepEnd; // <== moved to fields
private int shallowEnd; // <== moved to fields
private class InnerDrawingPanel extends JPanel {
@Override
protected void paintComponent(Graphics drawingBoard) {
drawingBoard.setColor(Color.yellow); // <== drawing code now here
drawingBoard.fillRect(0, 0, 250, 250);
drawingBoard.setColor(Color.black);
drawingBoard.drawLine(xPos, yPos, xPos + swimmingPoolLength, yPos); // the top line
drawingBoard.drawLine(xPos, yPos, xPos, yPos + deepEnd); // the left line
drawingBoard.drawLine(xPos + swimmingPoolLength, yPos, xPos + swimmingPoolLength, yPos + shallowEnd); // the right line
drawingBoard.drawLine(xPos, yPos + deepEnd, xPos + swimmingPoolLength, yPos + shallowEnd); // the bottom line
}
}
public static void main(String[] args) {
SwimingPoolCalculator swimingPoolCalculator = new SwimingPoolCalculator();
swimingPoolCalculator.createGUI();
}
private void createGUI(){
frame = new JFrame("Swiming Pool Calculator");
primaryJPanel = new JPanel();
primaryJPanel.setPreferredSize(new Dimension(250, 500));
drawingJPanel = new InnerDrawingPanel(); // <== use inner class
drawingJPanel.setPreferredSize(new Dimension(250, 300));
drawingJPanel.setBackground(Color.yellow);
shallowJLabel = new JLabel("S End");
deepJLabel = new JLabel("D End");
shallJSlider = new JSlider(JSlider.HORIZONTAL, 10, 100, 10);
deepJSlider = new JSlider(JSlider.HORIZONTAL, 50, 200, 100);
shallJSlider.addChangeListener(this);
deepJSlider.addChangeListener(this);
resultTextField = new JTextField(15);
primaryJPanel.add(drawingJPanel);
primaryJPanel.add(shallowJLabel);
primaryJPanel.add(shallJSlider);
primaryJPanel.add(deepJLabel);
primaryJPanel.add(deepJSlider);
primaryJPanel.add(resultTextField);
frame.getContentPane().add(primaryJPanel);
frame.pack();
frame.setVisible(true);
// why the first call does not draw any line?
shallowEnd = deepJSlider.getValue(); // <== now update fields
deepEnd = shallJSlider.getValue();
drawingJPanel.repaint(); // <== trigger repaint
}
private void calculateVolume(double averageDepth){
int swimmingPoolVolume = (int)(averageDepth * swimmingPoolLength * swimmingPoolWidth);
resultTextField.setText("Volume: " + swimmingPoolVolume);
}
@Override
public void stateChanged(ChangeEvent e) {
shallowEnd = shallJSlider.getValue(); // <== update fields
deepEnd = deepJSlider.getValue();
double averageDepth = (shallowEnd + deepEnd) / 2;
drawingJPanel.repaint(); // <== trigger repaint
calculateVolume(averageDepth);
}
}
答案 1 :(得分:0)
Swing可能在你画完后重新绘制JPanel。 Swing可以随时重新绘制组件,无论出于何种原因。因此,您不应使用getGraphics
。
相反,您需要创建自己的组件类(扩展现有组件,例如JPanel
),并覆盖paintComponent
。
有关详细信息,请参阅this question。