JRE版本1.7更新3
预期行为
当我运行程序时,一切都按预期进行,一切顺利。当我单击“停止”JButton
时,动画停止,并且相同的JButton
上的文本更改为“开始”。现在,当我单击“球颜色”JButton
时,BALL
的颜色会改变,以及BALL颜色
JBUTTON
的颜色也会更改为BALL
的颜色。如果我按原样运行应用程序而不调整大小,则整个行为都有效。
意外行为
但是,当我通过拉动右侧
来调整大小
我的JFrame
时,就会显示出应用程序的意外行为,这意味着如果我按下STOP
JButton
,然后单击BALL COLOUR
按钮,则早先单击的JButton
的文本将再次更改为STOP
,当它不应该,并且BALL COLOUR
JButton
的颜色将保持不变或更改为BLUE
,当它应该更改为球的颜色。我附加了更多信息的图片。但是,如果您将其调整回原始大小或更接近,则事情将恢复正常。这是为什么?有任何想法或提示将不胜感激。
由于我的应用程序以上面所述的预期行为运行:
这里是意外行为
底线:
为什么应用程序在开始时
按照预期运行,但当通过拖动其右侧
进行调整大小
时,则不能按预期运行,但是如果再将其调整为原始大小或更接近,则事情就会恢复正常,它按预期工作?
考虑到情况,我是否做错了什么,还是说这正是我应该使用SwingWorker
的情况,或者这是与Layout
有关的问题,或者是与Content Pane
有关的隐藏问题。请给予一些指导。
这是我使用的代码,我已将其最小化,因为我认为这可以展示我的问题:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BallAnimation
{
private int x;
private int y;
private boolean positiveX;
private boolean positiveY;
private boolean isTimerRunning;
private int speedValue;
private int diameter;
private DrawingArea drawingArea;
private Timer timer;
private int colourCounter;
Color[] colours = {
Color.BLUE.darker(),
Color.MAGENTA.darker(),
Color.BLACK.darker(),
Color.RED.darker(),
Color.PINK.darker(),
Color.CYAN.darker(),
Color.DARK_GRAY.darker(),
Color.YELLOW.darker(),
Color.GREEN.darker()
};
private Color backgroundColour;
private Color foregroundColour;
private ActionListener timerAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
x = getX();
y = getY();
drawingArea.setXYColourValues(x, y, backgroundColour
, foregroundColour);
}
};
private JPanel buttonPanel;
private JButton startStopButton;
private JButton speedIncButton;
private JButton speedDecButton;
private JButton resetButton;
private JButton colourButton;
private JButton exitButton;
private ComponentAdapter componentAdapter = new ComponentAdapter()
{
public void componentResized(ComponentEvent ce)
{
timer.restart();
startStopButton.setText("STOP");
isTimerRunning = true;
}
};
public BallAnimation()
{
x = y = 0;
positiveX = positiveY = true;
speedValue = 1;
colourCounter = 0;
isTimerRunning = false;
diameter = 50;
backgroundColour = Color.WHITE.brighter();
foregroundColour = colours[colourCounter];
timer = new Timer(10, timerAction);
}
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Ball Animation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
drawingArea = new DrawingArea(x, y
, backgroundColour, foregroundColour, diameter);
drawingArea.addComponentListener(componentAdapter);
frame.add(makeButtonPanel(), BorderLayout.LINE_END);
frame.add(drawingArea, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private JPanel makeButtonPanel()
{
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(0, 1));
buttonPanel.setBorder(BorderFactory.createLineBorder(
Color.DARK_GRAY, 5, true));
startStopButton = new JButton("START");
startStopButton.setBackground(Color.GREEN.darker());
startStopButton.setForeground(Color.WHITE.brighter());
startStopButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
System.out.println("START/STOP JButton Clicked!");
if (!isTimerRunning)
{
startStopButton.setText("STOP");
timer.start();
isTimerRunning = true;
buttonPanel.revalidate();
buttonPanel.repaint();
}
else if (isTimerRunning)
{
startStopButton.setText("START");
timer.stop();
isTimerRunning = false;
buttonPanel.revalidate();
buttonPanel.repaint();
}
}
});
startStopButton.setBorder(BorderFactory.createLineBorder(
Color.WHITE, 4, true));
buttonPanel.add(startStopButton);
colourButton = new JButton("BALL COLOUR");
colourButton.setBackground(colours[colourCounter]);
colourButton.setForeground(Color.WHITE);
colourButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
System.out.println("COLOUR JButton Clicked!");
//timer.restart();
colourCounter++;
if (colourCounter == 9)
colourCounter = 0;
foregroundColour = colours[colourCounter];
drawingArea.setXYColourValues(x, y, backgroundColour
, foregroundColour);
//drawingArea.setForegroundForBall(foregroundColour);
colourButton.setBackground(foregroundColour);
colourButton.revalidate();
colourButton.repaint();
//timer.start();
}
});
colourButton.setBorder(BorderFactory.createLineBorder(
Color.WHITE, 2, true));
buttonPanel.add(colourButton);
exitButton = new JButton("EXIT");
exitButton.setBackground(Color.RED.darker());
exitButton.setForeground(Color.WHITE.brighter());
exitButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
System.out.println("EXIT JButton Clicked!");
timer.stop();
System.exit(0);
}
});
exitButton.setBorder(BorderFactory.createLineBorder(
Color.RED.darker().darker(), 4, true));
buttonPanel.add(exitButton);
return buttonPanel;
}
private int getX()
{
if (x < 0)
positiveX = true;
else if (x >= drawingArea.getWidth() - diameter)
positiveX = false;
return (calculateX());
}
private int calculateX()
{
if (positiveX)
return (x += speedValue);
else
return (x -= speedValue);
}
private int getY()
{
if (y < 0)
positiveY = true;
else if (y >= drawingArea.getHeight() - diameter)
positiveY = false;
return (calculateY());
}
private int calculateY()
{
if (positiveY)
return (y += speedValue);
else
return (y -= speedValue);
}
public static void main(String... args)
{
Runnable runnable = new Runnable()
{
public void run()
{
new BallAnimation().createAndDisplayGUI();
}
};
SwingUtilities.invokeLater(runnable);
}
}
class DrawingArea extends JComponent
{
private int x;
private int y;
private int ballDiameter;
private Color backgroundColor;
private Color foregroundColor;
public DrawingArea(int x, int y
, Color bColor, Color fColor, int dia)
{
this.x = x;
this.y = y;
ballDiameter = dia;
backgroundColor = bColor;
foregroundColor = fColor;
setBorder(BorderFactory.createLineBorder(
Color.DARK_GRAY.darker(), 5, true));
}
public void setXYColourValues(int x, int y
, Color bColor, Color fColor)
{
this.x = x;
this.y = y;
backgroundColor = bColor;
foregroundColor = fColor;
repaint();
}
public Dimension getPreferredSize()
{
return (new Dimension(500, 400));
}
public void paintComponent(Graphics g)
{
g.setColor(backgroundColor);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(foregroundColor);
g.fillOval(x, y, ballDiameter, ballDiameter);
}
}
**最新编辑:**
createLineBorder
的第3个参数后!)。你显然正在使用1.7(考虑到第3个参数是在7中引入的)。这可能是正在使用的JRE中的错误吗? - Andrew ThompsonsetLayout(new FlowLayout(FlowLayout.LEFT));
,你说得对:-),因为如果我最大化窗口,一切都正常,只有当我通过拖动右侧来调整大小时,它才会出现这种奇怪的行为。我可能会再在其他地方测试一下,再次感谢您的帮助 :-) - nIcE cOwJButton
的整个setBorder(...)
语句,即使那样也无法解决问题。但是回到1.6后,问题得到了解决。所以事情已经解决了,但是是什么原因导致的,还是个谜 :-) - nIcE cOw