Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > awt или swing


Автор: elnino 3.1.2005, 01:04
Создается JWindow, на который я хочу добавить лэйбл:

Код

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
 
 JWindow loadingMonitor = new JWindow();
 
 JLabel loadingStatusLabel = new JLabel();
 
 loadingStatusLabel.setText( "Loading, please wait..." );
 
 int lmWidth = 300;
 
 int lmHeight = 200;  
 
 loadingMonitor.setSize( lmWidth, lmHeight );
 
 loadingMonitor.setLocation( (screenSize.width - lmWidth) / 2, (screenSize.height - lmHeight) / 2 );
 
 loadingMonitor.setLayout( new BorderLayout() );
 
 loadingMonitor.setBackground( new Color( 238, 238, 238 ) );
 
 loadingMonitor.add( loadingStatusLabel );
 
 loadingMonitor.setVisible( true );


Этот код не работает.
Проблема в том, что окно выводится, а вот метка -- нет.
Если изменить тип loadingStatusLabel на Label, то метка отобразится, но при этом я не могу использовать возможности swing. Что делать? Спасибо.

Автор: Domestic Cat 3.1.2005, 02:44
У меня все показывает.
Попробуй заменить этот код на эквивалентный, но более простой:
Код

 JWindow loadingMonitor = new JWindow();
 JLabel loadingStatusLabel = new JLabel("Loading, please wait...");
 int lmWidth = 300;
 int lmHeight = 200;  
 loadingMonitor.setSize( lmWidth, lmHeight );
 loadingMonitor.setLocationRelativeTo(null);
 loadingStatusLabel.setOpaque(true);
 loadingStatusLabel.setBackground( new Color( 238, 238, 238) );
 loadingMonitor.add( loadingStatusLabel, BorderLayout.CENTER );
 loadingMonitor.setVisible( true );

Если все будет так же, будем смотреть.

Автор: Domestic Cat 3.1.2005, 02:54
М
 
Кстати, постарайся выбирать более подходящие названия для тем.
А вообще - всегда приятно видеть на форуме новых людей :)

Автор: igon 3.1.2005, 11:44
Из доки на JWindow:
Цитата
The contentPane should be the parent of any children of the JWindow. From the older java.awt.Window object you would normally do something like this:        window.add(child);
However, using JWindow you would code:        window.getContentPane().add(child);
The same is true of setting LayoutManagers, removing components, listing children, etc. All these methods should normally be sent to the contentPane instead of the JWindow itself.


Цитата
Этот код не работает.
Проблема в том, что окно выводится, а вот метка -- нет.

Цитата
У меня все показывает


Хм, а у меня оригинальный код даже не компилится smile
После задействования contentPane - все заработало smile

Код

...
loadingMonitor.getContentPane().setLayout( new BorderLayout() );
...
loadingMonitor.getContentPane().add( loadingStatusLabel );
...



Автор: Domestic Cat 3.1.2005, 17:03
Цитата(igon @ 3.1.2005, 02:44)
Хм, а у меня оригинальный код даже не компилится


На самом деле ругаться будет 1.4.х, хотя все скомпилится, но не запустится; 1.5 отсутствие контентпейн прощает, т.к. add перегружен:

Цитата
The JWindow component contains a JRootPane  as its only child. The contentPane should be the parent  of any children of the JWindow.  As a conveniance add and its variants, remove and  setLayout have been overridden to forward to the  contentPane as necessary. This means you can write:
      window.add(child);

And the child will be added to the contentPane.

Автор: igon 3.1.2005, 19:59
Надо бы рекомендовать вопрошающим указывать версию JDK.
И переходить на 1.5 smile

Автор: elnino 5.1.2005, 00:12
Спасибо, что обратили внимание на мой вопрос.

Все равно не работает, и дело здесь, насколько я понял, не в этом коде. Все советы igon справедливы, а альтернативный код Domestic Cat не менее работоспособен, чем приведенный мной в самом начале. Но это касается тех случаев, когда этот код запускается в отдельном классе примитивного проекта.

Здесь все несколько сложнее, может быть причина в этом?

То есть окно loadingMonitor создается вместе с loadingStatusLabel, после чего моя программа начинает активные действия как, например, загрузка иконок и курсоров, установка сетевых соединений и передача данных через сокеты по сети. Может ли статься такое, что ресурсов моего компа не хватает, для того чтобы нормально перерисовывать loadingMonitor?

Понимаю, звучит глупо, но если специально сделать так, чтобы в процессе загрузки основной программы (то есть как раз в то время, когда я наблюдаю на экране ПУСТОЙ loadingMonitor) вылетел Exception, то в loadingMonitor моментально появляется loadingStatusLabel с текстом, соответствующим состоянию загрузки программы на момент вылета этого самого Exception...

P.S. Версия java, которой я пользуюсь jdk-1_5_0_01-windows-i586-p.exe
P.P.S. Celeron 333MHz, 196 оперативки <= мой зверь smile

Автор: Domestic Cat 5.1.2005, 00:20
Вопрос в том, где ты в программе пытаешься показать это окно. Перенеси его в main - что будет?
Если этот код находится в методе листенера (типа actionPerformed), добавь
Код

Runnable runner = new Runnable() {
  public void run() {
                            // здесь твой код с окном
  }
 };
SwingUtilities.invokeLater(runner);

Автор: elnino 5.1.2005, 01:44
Финиш! Перепробовал все, что знал. Включая invokeLater(). Уж куда только я его не вставлял...

Вопрос остался открытым: чем отличается, к примеру, JLabel от Label, таким, что при всех описанных выше действиях Label видно всегда и без проблем, а JLabel - только при возникновении исключительной ситуации?

Domestic Cat, ты права: этот злополучный код выполняется в actionListener() кнопки.

Вне его, как ты понимаешь, проблем с окном "loadingMonitor" не возникает.

P.S. Кстати, при использовании invokeLater() не видно даже окна (до исключения)

Автор: Domestic Cat 5.1.2005, 01:50
Цитата(elnino @ 4.1.2005, 16:44)
Domestic Cat, ты права:


Гыыы я пока пол не менял

Возьми весь код, не относящийся к окну, и помести его в отдельный тред:
Код

Thread thread = new Thread()
{
     public void run()
     {
           // сюда
     }
};
thread.start();

а код с окном оставь в invokeLater. Ну и смотри - будет появляться или нет.

Автор: elnino 5.1.2005, 20:44
2 Domestic Cat: уупс, гранд сори smile, сам не знаю, как так вышло, извини

Есть предложение: для демонстрации всего вышесказанного, взять вот этот код:

Код

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SwingAndAWTComparision {

private JWindow window;
private JButton closeButton;
// private Button closeButton;
private JButton demonstrateButton;
private int myWidth = 300;
private int myHeight = 30;  
final long iterationsNumber = 10000000;  

public SwingAndAWTComparision() {
 window = new JWindow();  
 closeButton = new JButton( "Close" );  
 demonstrateButton = new JButton( "Show window" );  
//  demonstrateButton = new Button( "Show window" );    
 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();      
 window.setSize( myWidth, myHeight );    
 window.setLocation( (screenSize.width - myWidth) / 2, (screenSize.height - myHeight) / 2 );            Container contentPane = window.getContentPane();  
 contentPane.setLayout( new GridLayout( 1, 2 ) );  
 contentPane.add( demonstrateButton );  
 contentPane.add( closeButton );  
 
 closeButton.addActionListener( new ActionListener() {
  public void actionPerformed( ActionEvent e ) {
   System.exit( 0 );
  }
 });
 
 
 demonstrateButton.addActionListener( new ActionListener() {
  public void actionPerformed( ActionEvent e ) {
//    SwingUtilities.invokeLater( new Runnable()
//    {
//     public void run()
//     {
     demonstrateButton.setEnabled( false );      
     JWindow demoWindow = new JWindow();      
     demoWindow.setSize( myWidth, myHeight );      
     demoWindow.setLocation( window.getX(), window.getY() - myHeight );       Container contentPane = demoWindow.getContentPane();    
     JLabel demoJLabel = new JLabel( "JLabel" );      
     Label demoLabel = new Label( "Label" );      
     contentPane.setLayout( new GridLayout( 1, 2 ) );    
     contentPane.add( demoJLabel );      
     contentPane.add( demoLabel );      
     demoWindow.setVisible( true );        
//     }    
//    });        
   for( int i = 0; i < iterationsNumber; i++ )      
   {                                                                  
    Math.cos( i );                                        
   }                                                                  
  }
 });  
 window.setVisible( true );
}

public static void main( String[] args )
{
 SwingAndAWTComparision demo = new SwingAndAWTComparision();
}
}




...и потестить его у себя. У кого какие комментарии?

Скажу сразу, что происходит у меня: Label видно сразу вместе с окном, а JLabel не появляется до тех пор, пока цикл не закончит свою работу. Если же раскомментировать строки с "invokeLater()", то до окончания работы цикла не появляется даже окно...

У вас так же или это у меня глюк? Не поленитесь, пожалуйста smile

P.S. Сори за неудобочитаемость кода, не хотел занимать слишком много места

Автор: Domestic Cat 5.1.2005, 21:22
Я ж говoрил - сделай так:
Код

demonstrateButton.addActionListener(new ActionListener()
{
   public void actionPerformed(ActionEvent e)
   {
       SwingUtilities.invokeLater(new Runnable()
       {
           public void run()
           {
               demonstrateButton.setEnabled(false);
               JWindow demoWindow=new JWindow();
               demoWindow.setSize(myWidth,myHeight);
               demoWindow.setLocation(window.getX(),window.getY()-myHeight);
               Container contentPane=demoWindow.getContentPane();
               JLabel demoJLabel=new JLabel("JLabel");
               Label demoLabel=new Label("Label");
               contentPane.setLayout(new GridLayout(1,2));
               contentPane.add(demoJLabel);
               contentPane.add(demoLabel);
               demoWindow.setVisible(true);
               }
           });
       Thread t = new Thread()
       {
           public void run()
           {
               for(int i=0;i<iterationsNumber;i++)
               {
                   Math.cos(i);
               }
           }
       };
       t.start();
   }
   });


У тебя тред диспетчерa вынужден считать косинусы вместo тогo чтобы лабел рисовать.
Добавлено @ 21:24
Насчет лейблов - у меня рисуются оба (с учетом моего кода).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)