2017-02-04 15 views
0

я работал на примере в Learning Java: 4-е издание от O'Reilly, когда я наткнулся на эту программу:Почему текст в этом JFrame не мигает?

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, поэтому любая помощь будет принята с благодарностью.

ответ

3

Проблема заключается в том, что вы на самом деле не перекрывая метод paintComponent так
paintComponenet != paintComponent

Всегда предварительно ПЭНД все методы, которые вы думаете вы переопределение с @Override аннотацию, так как таким образом компилятор будет warn вы во время компиляции, когда ваши предположения неверны.

Также проблема со стороной: вызовите метод 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); 
} 

Myself, я хотел бы использовать Swing, таймер и JLabel, чтобы сделать это, а не нарезания резьбы и живописи.

Или, по крайней мере, качающийся таймер. Например:

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()); 
    } 
} 
+0

Большое вам спасибо. Это было очень полезно –

+0

@NiteshKartha: добро пожаловать. Обратите внимание на изменения. –