2012-04-29 3 views
7

Java/Eclipse IDE здесь.JButtons внутри JPanels с GridLayout JFrame

У меня есть один JFrame, который установлен в GridLayout размера NxN. N задается пользователем в командной строке в начале программы. JButtons в шаблоне NxN добавляются в окно в JPanels, устанавливаются в местоположении GridLayout (я думаю).

Нужен ли каждому JButton собственный JPanel для использования GridLayout? У меня создается впечатление, что вы можете настроить только один JPanel для всех кнопок и установить JPanel в GridLayout для JButtons. Я хочу добавить еще один JPanel слева от массива кнопок, чтобы отображать нажатия кнопок (JLabel) и кнопку сброса внутри той же левой JPanel.

Здесь (немного) мой код, где N задается пользователем, система мой фоновые процессы класса, и ButtonEvent класс для ActionListener/actionPerformed:

JFrame window = new JFrame(""); 
GridLayout layout = new GridLayout(N,N); 
window.setLayout(layout); 

for (int row = 0; row < N; row++){ 
    for (int col = 0; col < N; col++){ 
     JPanel panel = new JPanel(); 
     JButton b = new JButton ("("+row+","+col+")"); 
     window.add(b).setLocation(row, col); 
     panel.add(b); 
     b.addActionListener(new ButtonEvent(b, system, row, col)); 
     window.add(panel); 
    } 
} 

window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
window.pack(); 
window.setVisible(true); 

И это то, что у меня есть (N = 4):

http://i.imgur.com/nbQoM.png

Здесь (приблизительно), что я ищу (N = 4):

http://i.imgur.com/SiVWO.png

Все, что мне нужно/нужно - это два (или более) JPanels, которые настроены примерно так же, как и выше, и все планировщики макетов, которые я пробовал, не играют хорошо с макетом GridLayout JFrame.

Предлагаются любые рекомендации относительно лучшего решения.

Спасибо!

ответ

11

Вот попробуйте этот пример кода:

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

public class LayoutExample extends JFrame 
{ 
    private static final String INITIAL_TEXT = "Nothing Pressed"; 
    private static final String ADDED_TEXT = " was Pressed"; 
    private JLabel positionLabel; 
    private JButton resetButton; 
    private static int gridSize = 4; 

    public LayoutExample() 
    { 
     super("Layout Example"); 
    } 

    private void createAndDisplayGUI() 
    {  
     setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     JPanel contentPane = new JPanel(); 
     contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 20)); 
     contentPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2)); 

     JPanel leftPanel = new JPanel(); 
     leftPanel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2)); 
     leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));  
     JPanel labelPanel = new JPanel(); 
     positionLabel = new JLabel(INITIAL_TEXT, JLabel.CENTER); 
     JPanel buttonLeftPanel = new JPanel(); 
     resetButton = new JButton("Reset"); 
     resetButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent ae) 
      { 
       positionLabel.setText(INITIAL_TEXT); 
      } 
     }); 
     labelPanel.add(positionLabel); 
     buttonLeftPanel.add(resetButton); 
     leftPanel.add(labelPanel); 
     leftPanel.add(buttonLeftPanel); 

     contentPane.add(leftPanel); 

     JPanel buttonPanel = new JPanel(); 
     buttonPanel.setLayout(new GridLayout(gridSize, gridSize, 10, 10)); 
     for (int i = 0; i < gridSize; i++) 
     { 
      for (int j = 0; j < gridSize; j++) 
      { 
       JButton button = new JButton("(" + i + ", " + j + ")"); 
       button.setActionCommand("(" + i + ", " + j + ")"); 
       button.addActionListener(new ActionListener() 
       { 
        public void actionPerformed(ActionEvent ae) 
        { 
         JButton but = (JButton) ae.getSource(); 
         positionLabel.setText(
          but.getActionCommand() + ADDED_TEXT);       
        } 
       }); 
       buttonPanel.add(button); 
      } 
     } 
     contentPane.add(buttonPanel); 

     setContentPane(contentPane); 
     pack(); 
     setLocationByPlatform(true); 
     setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     if (args.length > 0) 
     { 
      gridSize = Integer.parseInt(args[0]); 
     } 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new LayoutExample().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

ВЫВОД:

Start After Click

+1

+1 См. Также этот [пример] (http://stackoverflow.com/a/7706684/230513). – trashgod

+1

@trashgod: Спасибо за удаление этой большой ошибки, так как теперь по крайней мере она будет работать, даже без каких-либо аргументов :-). Мой чек раньше был бесполезным, LOL. –

+0

Ницца! Мне нравится, как это изменяет размеры (или, фактически, не изменяет размер). Сообщение trashgod ниже объясняет, почему именно это функционирует как таковое. Благодаря! – Avertheus

7

Нужен ли каждому JButton свой собственный JPanel для использования GridLayout?

Нет. Добавить и установитьЗагрузить на JFrame не делать то, что они кажутся. JFrame - это контейнеры верхнего уровня, и лучше организовать ваш контент в JPanels.

Вы должны организовать панели в таком виде:

----JPanel----------------------------| 
| ---LeftPanel--- ---ButtonsPanel--- | 
| |    | |    | | 
| |    | |    | | 
| |    | | GridLayout(N,N)| | 
| |    | |    | | 
| |    | |    | | 
| --------------- ------------------ | 
--------------------------------------- 

Затем добавьте JPanel в JFrame. Также поместите панели в отдельно классах:

class BPanel extends JPanel { 
    public BPanel() { 
     GridLayout layout = new GridLayout(N,N, hgap, vgap); 
     setLayout(layout); 
     for (int row = 0; row < N; row++){ 
      for (int col = 0; col < N; col++){ 
       JButton b = new JButton ("("+row+","+col+")"); 
       add(b).setLocation(row, col); 
       b.addActionListener(new ButtonEvent(b, system, row, col)); 
      } 
     } 
    } 
} 
class LeftPanel extends JPanel { 
.... 
} 

class MainFrame extends JFrame { 
    public MainFrame() { 
     JPanel p = new JPanel(); 
     p.add(new LeftPanel()); 
     p.add(newButtonsPanel()); 
     add(p); 
    } 
} 
+1

Хороший ответ. Великое искусство ASCII! См. Также [Вложенный пример компоновки] (http://stackoverflow.com/a/5630271/418556). –

+0

Да, похоже, это сработало для меня. Теперь у меня есть все мои JPanels в разных классах и один JPanel для GridLayout. Спасибо за объяснение! – Avertheus

3

Одним из преимуществ предоставления каждой кнопки (или группа кнопок), ее панель состоит в том, что вложенная панель может отличаться nt. В этом example каждое гнездо ButtonPanel имеет значение по умолчанию FlowLayout, поэтому размер кнопки остается неизменным по мере изменения размера контейнера.

+0

Это интересно, на самом деле, это то, что я понял, когда я прочитал первый ответ на эту тему от @ixos, поэтому для удовольствия я сел, чтобы делать то, что хотел OP, и я понял, что этот «размерный аспект» вызывает проблемы на «левой панели», поэтому эти два отдельных «JPanel's» для «JButton» и «JLabel» ', но то, что вы предложили для каждого' JButton' 'JPanel', мне понравилось :-) –

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