2016-11-24 9 views
1

Что касается причин тестирования, я попытался открыть окно JDialog с панелью и ее содержимым основного фрейма приложения. Поскольку у меня уже было что-то там, я хотел посмотреть, могу ли я просто установить JDialogs contentPane на тот, который я передал. Таким образом, в simplyfied форме это сходились:Передача контейнеров между JFrame и JDialog, вызывающими недостающие панели?

testsforSO.java:

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class testsforSO extends JFrame { 

    private static final long serialVersionUID = -3890178393751567629L; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        testsforSO frame = new testsforSO(); 
        frame.setSize(300, 300); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public testsforSO() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setTitle("I am the Frame"); 
     getContentPane().setLayout(new BorderLayout(0, 0)); 

     JPanel panel = new JPanel(); 
     panel.setLayout(null); 

     JButton btnRestart = new JButton("Restart"); 
     btnRestart.setBounds(10, 10, 50, 50); 
     btnRestart.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       testsforSO.main(null); 
       dispose(); 
      } 
     }); 
     panel.add(btnRestart); 
     getContentPane().add(panel); 
     repaint(); 

// -----------DELETE These comments------------- 
//  JDialog myDialg = new JDialog(this); 
//  myDialg.setContentPane(panel); 
//  myDialg.setVisible(true); 
//  myDialg.setSize(300,300); 
//  myDialg.setLocation(new Point(250, 250)); 
//  myDialg.setTitle("I am Dialog from within the script"); 

     myDialog.main(panel); 
    } 
} 

и myDialog.java:

import java.awt.Container; 
import java.awt.EventQueue; 

import javax.swing.JDialog; 

public class myDialog extends JDialog { 

    private static final long serialVersionUID = 7079322237622743228L; 

    public static void main(Container myContainer) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        myDialog frame = new myDialog(myContainer); 
        frame.setVisible(true); 
        frame.setContentPane(myContainer); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public myDialog(Container myContainer) { 
     setContentPane(myContainer); 

     getContentPane().setLayout(null); 

     setBounds(200,200,200,200); 

    } 

} 

При запуске основной рамы я предполагал, что это будет содержать кнопку перезапуска, а также как это делает диалог. Но интересно было только диалог с кнопкой.
Однако при попадании на него основной кадр должным образом перезагрузился, было установлено второе диалоговое окно, и оно снова содержало кнопку. На этот раз, однако, основной кадр тоже имел кнопку, без каких-либо функций. Нажатие на него абсолютно ничего не делает.

Затем я попытался продолжить и проверил, изменится ли это поведение, если я добавлю диалог непосредственно в код основных приложений (см. Прокомментированные строки), и, снова запустив приложение, только диалоговое окно в своем классе показало кнопку. Даже нажатие этой кнопки теперь перезапустилось должным образом, но кнопка не будет отображаться ни в одном другом окне, кроме одиночного объявленного диалога.

Что мне здесь не хватает и как я могу реорганизовать свой код для правильной работы, даже если это вообще так?

ответ

3

Поймите, что компоненты Swing могут находиться только в одном контейнере, и, хотя вы можете видеть визуальный остаток компонента в контейнере, фактический компонент присутствует только в последнем контейнере, добавленном к нему.

Сам, если бы я хотел, чтобы диалоговое окно и jframe имели одинаковые компоненты панели содержимого, я бы создал фабричный метод для создания contentPane, а затем использовал его для создания двух уникальных, но идентичных contentPanes.

Кроме того, я был бы упущен, если бы не упомянул о вашем использовании нулевых макетов. Хотя нулевые макеты и setBounds() могут показаться новичкам Swing, как самый простой и лучший способ создания сложных графических интерфейсов, чем больше Swing GUI вы создадите более серьезные трудности, с которыми вы столкнетесь при их использовании. Они не будут изменять размеры ваших компонентов при изменении размера графического интерфейса, они являются королевской ведьмой для улучшения или поддержки, они полностью не выполняются при размещении в scrollpanes, они выглядят ужасно ужасно при просмотре на всех платформах или разрешениях экрана, отличных от исходного ,

К примеру, когда я запустил свой код, это диалог, который я видел:

enter image description here

Вы жёстко размер кнопки на слишком мал, чтобы показать свой текст на моей платформе. Если вы использовали менеджеры макетов и вызвали pack() в окне верхнего уровня, кнопка будет отображаться соответствующим образом.

+0

Я вижу. Спасибо за быстрый ответ! Так что это будет что-то вроде 'public Container panelFactory() {/ * make и return Container * /}, и я бы назвал его, когда хочу получить новый ... Эта кнопка, отображающаяся на кадре, действительно меня путала. – geisterfurz007

+0

@ geisterfurz007: он был внутри JFrame, хотя бы кратко, и поэтому вы его видели, но если вы перекрасили JFrame после создания диалога, скорее всего, он исчезнет. Например, когда я запускаю свой код, я вижу только кнопку в JFrame, когда я нажимаю кнопку в диалоговом окне. –

+0

@ geisterfurz007: side issue: у вас также никогда не будет кода, который называет основные методы, как вы делаете. –