2015-05-28 2 views
2

У меня нет цели для того, что я действительно делаю, просто пытаюсь разобраться с Java Swing. То, что я сейчас эти три переменные:Как работает размер JFrame?

int[] gridIterations = {10,10}; //how many JButtons are made each row/column 
    int[] frameSize = {600,600}; //size of the JFrame 
    int[] gridSize = {60,60}; //by gridSize, I mean size of the JButtons 

У меня также есть вложенный цикл, который использует эти переменные для создания сетки JButtons. Я бы ожидать сеток идеально подходит JFrame, однако это результат:

Grids cut off at the bottom and right edges of JFrame

После некоторого тестирования я понял, что кадр будет на самом деле только уместить все JButtons если размер (615, 631) Но я Интересно, почему он подходит только с этими параметрами и почему, из всех чисел, было бы это ? Насколько я понимаю, просто вычисление 60 * 10 должно равняться 600 и успешно использовать все кнопки в JFrame, но я, скорее всего, что-то не замечаю. Что это может быть? Благодарю.

+0

Я не слишком хорош с формулировкой; Прошу прощения за смутное название. Если кто-то может отредактировать его, чтобы сделать немного больше ... смысла? Я был бы очень признателен за это :) –

+1

Фактический размер кадра также составляет границу. – Constant

+0

Я попытался использовать 'frame.getContentPane(). SetSize()', но это только начинает кадр в этом маленьком маленьком окне в верхнем левом углу. –

ответ

4

Много сводится к требованиям содержания и менеджера компоновки. Вместо того, чтобы смотреть, «насколько большой» вам нужен кадр, сосредоточьтесь на объеме пространства, в котором нуждается контент. После этого кадр будет «упакован».

Это означает, что рамка будет «размер контента + размер рамки рамки» большой.

JFrame#pack принимает во внимание предпочтительный размер содержимого и автоматически добавляет в рамки рамки рамки.

Таким образом, единственное, что вам нужно, это позвонить JFrame#pack ПОСЛЕ завершения добавления к нему содержимое

Таким образом, на основе кода:

public class Testing { 

     public static void main(String[] args) { 
       JFrame frame = new JFrame("hi"); 

       for (int i = 0; i < 10; i++) { 
         JButton a = new JButton(); 
         a.setSize(20,20); 
         a.setLocation(20*i, 0); 
         frame.getContentPane().add(a); 

       } 
       frame.setLayout(null); 
       frame.pack(); 
       frame.setVisible(true); 
     } 

} 

Вы используете null макет. JFrame#pack будет использовать информацию, предоставленную менеджером макета, для определения «предпочтительного» размера общего содержимого.

Избегайте использования макетов null, идеальные макеты пикселей являются иллюзией в современном дизайне ui. Слишком много факторов, которые влияют на индивидуальный размер компонентов, ни один из которых вы не можете контролировать. Swing был разработан для работы с менеджерами компоновки в ядре, отбрасывая их, не приведет к возникновению проблем и проблем, которые вы будете тратить все больше и больше времени на исправление.

Скорее, фокусировка на абсолютном значении, которая будет варьироваться между ОС (и даже разными ПК с той же ОС), сосредоточена на пользовательском опыте.

Как, уже было показано, вы можете легко получить эту работу с помощью GridLayout

GridLayout

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

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

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      setLayout(new GridLayout(10, 10, 0, 0)); 
      for (int index = 0; index < 10 * 10; index++) { 
       JButton btn = new JButton(String.valueOf(index)) { 
        @Override 
        public Dimension getPreferredSize() { 
         return new Dimension(50, 50); 
        } 
       }; 
       add(btn); 
      } 
     } 

    } 

} 

Если вам нужна более сложного управления (т.е. глубина по ширине), вам может использовать GridBagLayout вместо

Посмотрите на Laying Out Components Within a Container, How to Use GridLayout и How to Use GridBagLayout для получения более подробной информации;)

+0

Эй, это значит иметь знак octothorpe/hash (tag)/tictactoe знак/номер? Потому что он показывает как «Недопустимый символ» для меня: O Извините, кстати, я все еще изучаю много нового о Java. –

+1

«#» - это просто мой способ сказать, что это поле или метод «экземпляр» (а не статический). Так что да, обычно это будет 'instanceOfJFrame.pack()';) – MadProgrammer

+0

О, я понимаю, что вы имеете в виду. В чем разница между этим и вторым вариантом, который сделал Constant? –

4

Размер JFrame включает в себя его вставки. Это в основном означает заголовок и границы.

GridLayout сделает это идеально для вас с гораздо меньшими усилиями.

grid layout

class GridButtons implements Runnable { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new GridButtons(4, 5)); 
    } 

    final int rows; 
    final int cols; 

    GridButtons(int rows, int cols) { 
     this.rows = rows; 
     this.cols = cols; 
    } 

    @Override 
    public void run() { 
     JFrame frame = new JFrame(); 
     JPanel grid = new JPanel(new GridLayout(rows, cols)); 

     for (int i = 0; i < (rows * cols); ++i) { 
      grid.add(new JButton() { 
       @Override 
       public Dimension getPreferredSize() { 
        return new Dimension(60, 60); 
       } 
      }); 
     } 

     frame.setContentPane(grid); 
     frame.pack(); 
     frame.setResizable(false); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 
} 
+0

[Должен ли я избегать использования методов Set (Preferred | Maximum | Minimum) в Java Swing?] (Http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize- methods-in-java-swi) – MadProgrammer

+1

@MadProgrammer Правда, но он работает для этого конкретного примера. С другой стороны, если бы кнопки имели текст или значок, я бы защищал его. (Но, как всегда, установка «абсолютных размеров» означает, что на разных разрешениях экрана будет отображаться другой размер ...) – Radiodef

+0

Да, но давайте попробуем не поощрять людей по пути, который приведет их к (более) неприятностям;) - Вместо этого вы могли бы переопределить метод 'getPreferredSize'' JButton;) – MadProgrammer

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