2013-07-30 3 views
1

Я проводил некоторое время, переучивая java, и здесь возникла своеобразная логическая ошибка.Ошибка JFrame Logic

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

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

     JFrame frame = new JFrame("Tester Frame"); 
     frame.setSize(400, 500); 

     JButton btn1 = new JButton("FOO"); 
     btn1.setSize(150, 50); 
     btn1.setLocation(45, 0); 

     JButton btn2 = new JButton("BAR"); 
     btn2.setSize(150, 50); 
     btn2.setLocation(205, 0); 

     Container content = frame.getContentPane(); 
     content.setBackground(Color.blue); 
     content.add(btn1); 
     content.add(btn2); 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    }//end main                           
} 

Я создал 2 объекта JButton, и они должны быть одного размера с разным расположением и текстом. Это, конечно, не так, кнопка «FOO» - это именно то, где и как я хочу, но кнопка «BAR» - это размер всего кадра.

Помощь!

ответ

4

1) Вы пытаетесь использовать Absolute LayoutManager через setSize и setLocation и т.д., но без вызова setLayout(null) на компоненте вы добавляете JButton с до. Однако это не лучшая практика в Swing.

При добавлении к JFrameContentPane расположение по умолчанию является BorderLayout, который добавляет компоненты по умолчанию положение BorderLayout.CENTER.

Есть прочитанный на A Visual Guide to Layout Managers

2) Также при использовании правильного LayoutManager вы бы опустить JFrame#setSize(..) вызов и заменить его JFrame#pack() перед установкой JFrame видимым.

3) Кроме того, есть прочитанный на Concurrency in Swing конкретно на The Event Dispatch Thread который диктует все компоненты распашные быть созданы на EDT через SwingUtillities.invokeXXX(..) блока:

SwingUtilities.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     //create and manipulate swing components here 
    } 
}); 

4) Также лучше использовать JFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);, поскольку это позволит любые другие потоки таймеры и т. д., чтобы продолжить выполнение даже после того, как был удален JFrame.

+3

Я думаю, что по умолчанию BorderLayout, но может быть и неправильным. – Kon

+0

@kon +1 yup спасибо за исправление было какое-то время;) –

+0

Не проблема! – Kon

0

Компоненты, добавленные в контейнер, отслеживаются в списке. Порядок списка определит порядок удержания компонентов между собой в контейнере. Если индекс не указывается при добавлении компонента в контейнер, он будет добавлен в конец списка (и, следовательно, к нижней части порядка укладки). В вашем коде кнопки сложены над другим. Вот почему вы получите эту ошибку (как вы думаете, это так). Это позволит решить вашу проблему: -

import javax.swing.*; 

import java.awt.*; 

class OP3 
{ 
    public static void main (String args[]) 
    { 

    JFrame frame = new JFrame("Tester Frame"); 
    frame.setSize(400, 500); 

    JButton btn1 = new JButton("FOO"); 
    btn1.setSize(150, 50); 
    btn1.setLocation(45, 0); 

     JButton btn2 = new JButton("BAR"); 
    btn2.setSize(150, 50); 
    btn2.setLocation(205, 0); 

     JPanel p = new JPanel(new FlowLayout()); 
     p.add(btn1); 
     p.add(btn2); 
     frame.add(p); 


     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    }//end main                           
} 
1

добавить:

frame.getContentPane().setLayout(null); 

Для кода после строки:

frame.setSize(400, 500); 
+1

Это неправильный способ использования надлежащего менеджера компоновки, отличного от Absolute. –

+1

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

+0

OP может * вручную * размер 'JButton' при необходимости через' setXXXSize' или переопределять 'getXXXSize' при использовании' LayoutManager', который соответствует его потребностям –

0

Просто добавить панель в рамку и добавить кнопки панель.

import javax.swing.*; 

import java.awt.*; 

class source 
{ 
    public static void main (String args[]) 
    { 

    JFrame frame = new JFrame("Tester Frame"); 
    frame.setSize(400, 500); 

    JPanel panel=new JPanel();//panel added here 
    panel.setSize(frame.size()); 
    panel.setLocation(0, 0); 

    JButton btn1 = new JButton("FOO"); 
    btn1.setSize(150, 50); 
    btn1.setLocation(45, 0); 

    JButton btn2 = new JButton("BAR"); 
    btn2.setSize(150, 50); 
    btn2.setLocation(205, 0); 

    panel.add(btn1); 
    panel.add(btn2); 

    Container content = frame.getContentPane(); 
    content.setBackground(Color.blue); 
    content.add(panel); 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 
}//endmain                           
+0

Абсолютный 'LayoutManager' - не самая лучшая практика при построении достойного графического интерфейса swing. –

+0

@David Kroukamp Ok спасибо. Я знаю основную JAVA, поэтому я оказал помощь как можно лучше. Я прочитаю больше об абсолютном LayoutManager. – zindarod