当我遇到这个程序时,我正在研究O' Reilly的学习Java:第4版中的一个例子:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloJava4 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
JFrame frame = new JFrame("HelloJava4");
frame.add(new HelloComponent4("Hello, Java!"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
class HelloComponent4 extends JComponent implements MouseMotionListener, ActionListener, Runnable {
String theMessage;
int messageX = 125, messageY = 95;
JButton theButton;
int colorIndex; //Current index into someColors
static Color[] someColors = {Color.black, Color.red, Color.green, Color.blue, Color.magenta};
boolean blinkState;
public HelloComponent4(String message){
theMessage = message;
theButton = new JButton("Change Color");
setLayout(new FlowLayout());
add(theButton);
theButton.addActionListener(this);
addMouseMotionListener(this);
Thread t = new Thread(this);
t.start();
}
public void paintComponenet(Graphics g){
g.setColor(blinkState ? getBackground() : currentColor());
g.drawString(theMessage, messageX, messageY);
}
@Override
public void mouseDragged(MouseEvent e){
messageX = e.getX();
messageY = e.getY();
repaint();
}
@Override
public void mouseMoved(MouseEvent e){}
@Override
public void actionPerformed(ActionEvent e){
if(e.getSource() == theButton)
changeColor();
}
synchronized private void changeColor(){
if(++colorIndex == someColors.length)
colorIndex = 0;
setForeground(currentColor());
repaint();
}
synchronized private Color currentColor(){
return someColors[colorIndex];
}
@Override
public void run(){
try{
while(true){
blinkState = !blinkState; //Toggle blinkState
repaint(); //show the change
Thread.sleep(300);
}
} catch(InterruptedException ie){}
}
}
该程序应该生成文本" Hello,Java!"在盒子里眨眼间。由于某种原因,文本甚至没有出现。 JButton说"改变颜色"是的,但它没有工作(或者我无法看到它工作,因为JFrame / HelloComponent4中没有文本)。
我不熟悉Swing或AWT,所以非常感谢任何帮助。
答案 0 :(得分:3)
问题是因为你没有真正重写paintComponent方法
paintComponenet != paintComponent
始终预先删除您认为的所有方法,并覆盖@Override
注释,因为这样编译器会在编译时警告你你的假设不正确的时候。
另外的问题是:在你自己的覆盖中调用super.paintComponent(g)
方法,以便组件自己做家务绘画,包括消除空像素。
public void paintComponenet(Graphics g) {
g.setColor(blinkState ? getBackground() : currentColor());
g.drawString(theMessage, messageX, messageY);
}
到此:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(blinkState ? getBackground() : currentColor());
g.drawString(theMessage, messageX, messageY);
}
我自己,我使用Swing Timer和JLabel来做这件事,而不是穿线和绘画。
或者至少是一个Swing Timer。例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class HelloJava4b extends JPanel {
// don't have component class implement listener interfaces
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
public static final Color[] COLORS = { Color.black, Color.red, Color.green, Color.blue,
Color.magenta };
private static final int TIMER_DELAY = 300;
private static final Font TEXT_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 40);
private int colorsIndex = 0;
private boolean blinkState = false;
private String text;
private int messageX = 125;
private int messageY = 95;
public HelloJava4b(String text) {
this.text = text;
add(new JButton(new ButtonAction("Change Color")));
// create Swing Timer and start
new Timer(TIMER_DELAY, new TimerListener()).start();
// create mouse listener and add
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
// size component per its preferred size
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Color c = blinkState ? getBackground() : COLORS[colorsIndex];
g.setColor(c);
// make rendering smoother
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setFont(TEXT_FONT); // and bigger
g.drawString(text, messageX, messageY);
}
// button's Action
private class ButtonAction extends AbstractAction {
public ButtonAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic); // alt-char hot key
}
@Override
public void actionPerformed(ActionEvent e) {
colorsIndex++;
colorsIndex %= COLORS.length;
}
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
blinkState = !blinkState;
repaint();
}
}
// my combination mouse listener and motion listener
private class MyMouse extends MouseAdapter {
private boolean moving = false;
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
moving = true;
messageX = e.getX();
messageY = e.getY();
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
// if not moving, then right button not pressed
if (moving) {
messageX = e.getX();
messageY = e.getY();
repaint();
moving = false;
}
}
@Override
public void mouseDragged(MouseEvent e) {
if (moving) {
messageX = e.getX();
messageY = e.getY();
repaint();
}
}
}
private static void createAndShowGui() {
HelloJava4b mainPanel = new HelloJava4b("Hello All!");
JFrame frame = new JFrame("Hello Java");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}