2013-11-08 5 views
0

Я новый ученик Java.Почему мой JLabel не показан?

Я создаю приложение GUI.

Этот класс получает номер от пользователя и показывает таблицу на фрейме.

Когда я запускаю свой класс, я ввожу число и нажимаю JButton, но JLabel на моем кадре не отображается.

Это не показывает мне почему нет.

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JTextField; 
import java.awt.event.*; 
//this Frame class use the association 
class Frame { 
    JFrame f; 
    JButton jb,jbclear; 
    JTextField jt; 
    JLabel jl1[]=new JLabel[10]; 
    EventHandler hand=new EventHandler(); 
    //constructor 
    Frame(){ 
     f=new JFrame("Hello"); 
     f.setSize(500,500); 
     f.setLayout(null); 

     JLabel jl=new JLabel("Enter the number"); 
     jl.setBounds(30,10,100,20); 
     f.getContentPane().add(jl); 

     jt=new JTextField(); 
     jt.setBounds(170,10,50,20); 
     f.add(jt); 

     jb=new JButton("Click"); 
     jb.setBounds(270,50,80,30); 
     f.add(jb); 
     jb.addActionListener(hand); 

     jbclear=new JButton("Clear"); 
     jbclear.setBounds(270,90,80,30); 
     f.add(jbclear); 
     jbclear.addActionListener(hand); 
     f.setVisible(true); 


    } 
    class EventHandler implements ActionListener{ 
     public void actionPerformed(ActionEvent e){ 
      if(e.getSource()==jb){ 
       int num=Integer.parseInt((jt.getText())); 
        for(int i=0;i<10;i++){ 
         int n=(num*i); 
         String s=String.valueOf(num)+" X "+i+" = "+n; 
         jl1[i]=new JLabel(s); 
        } 
        for(int i=0,k=80;i<10;i++){ 
        jl1[i].setBounds(30,k,150,10); 
        f.add(jl1[i]); 
        jl1[i].setVisible(true); 
        k=k+30; 
        } 

      } 
      if(e.getSource()==jbclear){ 
       for(int i=0;i<10;i++){ 
        jl1[i].setText(""); 
       } 
      } 

     } 
    } 






    public static void main(String [] args){ 
     new Frame(); 

    } 

} 

Можно ли добавить компонент после создания и отображения JFrame?

ответ

1

Вы создаете этикетки jl1[i]=new JLabel(s), но они не добавляются в контейнер.

Не используйте нулевой макет/SetBounds(), но выбрать подходящую (например, GridLayout или BoxLayout)

+0

', но они не добавляются в container.': они добавляются в кадр да, следовательно, они добавляются в контейнер , – Sage

+0

@Sage вы правы, что их добавили в фрейм, но добавление непосредственно к фрейму работает с java 6. Предыдущим версиям нужен контейнер, поэтому лучше определить контейнер и использовать его. – StanislavL

1

Ваша проблема в следующем:

1) добавить все компоненты в одном Манер, как и f.getContentPane().add(), при этом вы добавляете своих собеседников с f.getContentPane().add() и f.add() это разные контейнеры.

2) если вы добавляете компонент в видимую рамку/панель/контейнер, вы должны вызвать методы revalidate() и repaint() в контейнере после добавления, из-за которых без этих методов добавленный компонент будет невидим. Я изменить ActionListener в следующем пути (это делать то, что вы хотите):

class EventHandler implements ActionListener{ 
    public void actionPerformed(ActionEvent e){ 
     if(e.getSource()==jb){ 
      int num=Integer.parseInt((jt.getText())); 
       for(int i=0;i<10;i++){ 
        int n=(num*i); 
        String s=String.valueOf(num)+" X "+i+" = "+n; 
        jl1[i]=new JLabel(s); 
       } 
       for(int i=0,k=80;i<10;i++){ 
       jl1[i].setBounds(30,k,150,10); 
       f.getContentPane().add(jl1[i]); 

       k=k+30; 
       } 
       f.getContentPane().revalidate(); 
       f.getContentPane().repaint(); 

     } 
     if(e.getSource()==jbclear){ 
      for(int i=0;i<10;i++){ 
      f.getContentPane().remove(jl1[i]); 
      } 
      f.getContentPane().revalidate(); 
      f.getContentPane().repaint(); 
     } 

    } 
} 

JFrame revalidate

Я рекомендую вам попробовать использовать LayoutManager вместо setBounds() метод с нулевым макете.

1
   for(int i=0;i<10;i++){ 
       int n=(num*i); 
       String s=String.valueOf(num)+" X "+i+" = "+n; 
       jl1[i]=new JLabel(s); 
      } 
      for(int i=0,k=80;i<10;i++){ 
       jl1[i].setBounds(30,k,150,10); 
       f.add(jl1[i]); 
       jl1[i].setVisible(true); 

Ok, вы добавляете JLabel к JFrame, более точно панели содержимого фрейма, но вы не вызвали repaint() на JFrame обновить GUI. Просто позвоните, f.repiant(), как только вы закончите добавить labels тоже есть некоторые выходные для временного удовлетворения.

Можно ли добавить компонент после создания и отображения JFrame?

Да, но мы должны использовать надлежащий менеджер компоновки, после добавления компонента мы должны вызвать revalidate() и repaint() для отображения графического интерфейса пользователя соответствующим образом.

Теперь еще некоторые вещи:

  1. Не работать с Null макетом (или Абсолютной Layout)
  2. Все видимый флагу компоненты является true по умолчанию, вам не нужно вызывать setVisible(true) на таком компонент, за исключением окна приложения, например, JFrame
  3. Swing использует EDT для своей задачи рендеринга GUI.Следовательно, мы должны сделать все необходимое обновление для графического интерфейса пользователя, включая показ нашего приложения в первый раз после запуска, также должны быть помещены в EDT. SwingUtilies.invokeLater(new Runnabe(){}) сделать как раз.

Учебник:

  1. Concurrency in Swing
  2. Lesson: Laying Out Components Within a Container
+0

Не нужно повторно проверять(), когда были вызваны setBounds(). Revalidate просит LayoutManager установить границы. Не нужно вызывать этот код в SwingUtilies.invokeLater(). Достаточно назвать это непосредственно из actionPerformed() – StanislavL

+0

Не знаю, как ваш комментарий имеет отношение к моему ответу! возможно, я что-то упускаю. Когда мы используем менеджер компоновки, мы должны называть 'revalidate()' при добавлении нового компонента или удалении компонента, который я конкретно сказал. И нам нужно обновить GUI внутри EDT. Функция ActionPerfomed, вызываемая 'AnctionEvent', уже запускается внутри EDT. Но показ окна + обновление GUI из другого потока должно выполняться в EDT с помощью SwingUtilities. В настоящее время OP отображает главное окно (JFrame) из основного потока – Sage

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