2015-07-12 3 views
0

Благодарим за помощь. Я новичок, пробую что-то очень простое. Я хочу иметь окно (панель) с текстом (JLabel), которое меняется каждые несколько секунд. Все приложение отлично работает, за исключением обновляемого JLabel (текст меняется), но он не отображается в окне (панели). Окно сохраняет один и тот же текст от начала до конца, хотя у меня есть контрольные точки, которые говорят мне, что текст JLabel обновляется и изменяется. Я искал ту же проблему повсюду и нашел некоторые комментарии, но никто не помог. Кто-то сказал, что это ActionListener, но когда я избавился от него, это не изменило ситуацию. Кто-то сказал, что цикл в потоке не позволяет обновлять JLabel, поэтому я попытался использовать JLabel, и это обновление находится в отдельном потоке, и это тоже не сработало. Единственное, что я не пробовал, - это использовать swingWorker (не знаю, как это сделать). Попытка потока была связана с классом потока с помощью метода runnable. Опять же, таким образом все работало отлично, за исключением того, что JLabel не перекрашивал себя.JLabel на JPanel не обновляется, если setText от другого метода

Вот код без темы. Это все в одном классе.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.awt.event.WindowListener; 

import javax.swing.*; 





public class SWUI extends JFrame implements ActionListener { 
    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    private JPanel panel; 
    JLabel label; 
    private Font font; 


    //Set up the interface. SWUI is working perfectly 
SWUI() { 

     System.out.println("run started");  //just to check that the method gets called. 
     panel = new JPanel(); 
     panel.setLayout(new BorderLayout(1, 1)); 
     panel.setPreferredSize(new Dimension(1000, 400)); 
     panel.setBackground(Color.white); 
     getContentPane().add(panel); 

     label = new JLabel("Ready");     //These four statements are working 
     label.setHorizontalAlignment(JLabel.CENTER); 
     font = new Font("Comic Sans MS", Font.PLAIN, 70); 
     label.setFont(font); 

     panel.add(label, BorderLayout.CENTER); 

     System.out.println("run done and draw to start"); 

     label.setText("label is updatable");  //Checks that the whole method gets done and that the label is indeed able to get updated. It works. 

    } 


// draw() mostly sets the Frame up, names it, sets closing behavior. It's working. 
    public void draw() { 

     System.out.println("draw started");   //To check that the method is getting invoked. 

     SWUI frame = new SWUI(); 
     frame.setTitle("Sight Words Rock"); 

     WindowListener l = new WindowAdapter() { 
     public void windowClosing(WindowEvent e) { 
      System.exit(0); 
     } 
     }; 
     frame.addWindowListener(l); 

     frame.pack(); 
     frame.setVisible(true); 

     System.out.println("draw done");  //To check that the whole method went through. It's all working. 

    } 



    //Should change the label to 4 sentences every 1 second. The text of the label does change, but it doesn't show on the interface (panel). 
    private void updateLabel(String word){ 

     label.setText(word); 

     //label.revalidate();  //I tried these three statements one at a time and both together and they made no difference. 
     //label.updateUI(); 
     //label.repaint(); 

     System.out.println("The label now is: "+ label.getText()); //This confirms that the setText() is indeed changing the text 
                    // of the label, but it doesn't show on the interface. 
    } 


    //Main gets the draw() started to initiate the interface and gets the sentences changed and sent to updateLabel() every second. 
    public static void main(String args[]) 

     throws InterruptedException { 

     SWUI ui = new SWUI(); 
     ui.draw(); 


     String importantInfo[] = { 
      "Mares eat oats", 
      "Dogs eat oats", 
      "Little lambs eat ivy", 
      "A kid will eat ivy too" 
     }; 

     for (int i = 0; 
      i < importantInfo.length; 
      i++) { 
      //Pause for 1 second 
      Thread.sleep(1000); 

      //Print a message 
      System.out.println(importantInfo[i]); 

      ui.label.setText(importantInfo[i]); 
      ui.updateLabel(importantInfo[i]); 
     } 

    } 

    //This will come later once I figure how to fix the label. Someone else suggested that the problem were the listeners not letting the thread 
    // do the repainting(), but I tried getting rid of the "implements ActionListener" and the actionPerformed methods and it didn't make a 
    // difference. It still didn't work. 
    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     // TODO Auto-generated method stub 

    } 
} 
+0

Какой поток вы называете 'setText'? Помните, что все обновления компонентов swing должны быть сделаны на EDT, используйте 'SwingUtilities.invokeLater', если вам нужно запустить обновление из другого потока. –

+0

1) Используйте логическую и согласованную форму отступающих кодовых строк и блоков. Отступы предназначены для того, чтобы поток кода стал проще следовать! 2) Единственная пустая строка пробела в исходном коде - это все, что требуется *. Пустые строки после '{' или before '}' также типично избыточны. –

ответ

0

Ваш draw метод SWUI создает совершенно новый кадр, а ваши обновления идут к исходной раме, которая никогда не реально выставленного видно. Чтобы исправить, ваш метод рисования должен выглядеть более как это.

public void draw() { 

     System.out.println("draw started");   //To check that the method is getting invoked. 

     setTitle("Sight Words Rock"); 

     WindowListener l = new WindowAdapter() { 
     public void windowClosing(WindowEvent e) { 
      System.exit(0); 
     } 
     }; 
     addWindowListener(l); 

     pack(); 
     setVisible(true); 
    System.out.println("draw done");  //To check that the whole method went through. It's all working. 

} 
+0

Большое спасибо за подробное объяснение. Он отлично работал. –

+0

System.exit (0); in windowClosing == JFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) – mKorbel

+0

Не стесняйтесь добавлять edit @mKorbel. Я на самом деле не слишком много в этом разбираюсь, отступы - это корма, но лучше всего не подклассифицировать JFrame, и много способов, которыми это может быть лучше. – pvg

Смежные вопросы