Фиксированная ширина в GridBagLayout - PullRequest
4 голосов
/ 27 июля 2011

enter image description here

Я использую GridBagLayout для создания StatusBar, который выглядит как на картинке.У меня есть 4 области, поэтому у меня есть кнопка в первой, затем информационные сообщения во второй, и затем я хочу еще две (и у меня также есть пятая, чтобы сделать угол).

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

Как я могу это сделать?

Мой текущий код:

public MyStatusBar() {
        setLayout(new GridBagLayout());
        setPreferredSize(new Dimension(getWidth(), 23));
        GridBagConstraints c = new GridBagConstraints();

        botonDispositivo = new JButton("");
        this.setText(0, "Disconnected");
        URL imageUrl = getClass().getResource("resources/22x22/dispositivo01.png");
        this.setButtonImg(imageUrl);
        this.setButtonEnabled(false);


        c.gridx = 0;
        c.gridy = 0;
        c.fill = GridBagConstraints.BOTH;
        c.anchor = GridBagConstraints.WEST;
        c.gridwidth = 1;
        c.gridheight = 1;
        this.add(botonDispositivo, c);

        c.insets= new Insets(0,10,0,0);
        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.7;
        c.fill = GridBagConstraints.HORIZONTAL;
        msgLabel = new JLabel("");
        msgLabel.setPreferredSize(new Dimension(500, msgLabel.getHeight()));
        this.add(msgLabel, c);
        this.setText(1, "Waiting for potentiostat conection");

        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.0;
        c.fill = GridBagConstraints.NONE;
        this.add(new SeparatorPanel(Color.GRAY, Color.WHITE), c);

        c.gridx ++;
        c.gridy = 0;
        c.fill = GridBagConstraints.NONE;
        c.weightx = 0.0;
        overErrorLabel = new JLabel("");
        overErrorLabel.setSize(new Dimension(150, overErrorLabel.getHeight()));
        this.add(overErrorLabel, c);
        //this.setText(2, "");

        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.0;
        c.fill = GridBagConstraints.NONE;
        this.add(new SeparatorPanel(Color.GRAY, Color.WHITE), c);

        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.0;
        c.fill = GridBagConstraints.NONE;
        c.anchor = GridBagConstraints.EAST;
        timeLabel = new JLabel("");
        timeLabel.setMinimumSize(new Dimension(150, timeLabel.getHeight()));
        //timeLabel.setMaximumSize(new Dimension(150, timeLabel.getHeight()));
        this.add(timeLabel, c);
        //this.setText(3, "");


        JPanel rightPanel = new JPanel(new GridBagLayout());
        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.0;
        c.fill = GridBagConstraints.BOTH;
        rightPanel.add(new JLabel(new AngledLinesWindowsCornerIcon()), c);
        rightPanel.setOpaque(false);

        c.gridx ++;
        c.gridy = 0;
        c.fill = GridBagConstraints.BOTH;
        this.add(rightPanel, c);

        setBackground(SystemColor.control);
      }

Ответы [ 3 ]

12 голосов
/ 27 июля 2011

Вы устанавливаете предпочтительный, минимальный, максимальный и т. Д. Размер для разных ярлыков. Я думаю, все, что вам нужно, это установить вес X> 0 и заполнить param = HORIZONTAL ограничения для метки, размер которой вы хотите изменить, и weightX = 0 и fill-NONE для меток, размер которых вы не хотите изменять.

Также используйте ipadx, чтобы указать минимальный размер для меток.

4 голосов
/ 04 марта 2013

Если вы хотите, чтобы ячейка внутри GridBagLayout была фиксированной по ширине (или высоте), то для этого есть рабочее решение. Скажем, вы хотите, чтобы ячейка в точке (x, y) была фиксированной по ширине, но внутри JLabel есть переменное содержимое, которое необходимо изменить во время выполнения. Использование GridBagLayout затем переместит другие компоненты, если JLabel потребуется изменить размер, что приведет к изменению размера содержащейся ячейки. Чтобы противостоять этому, вы можете сделать одно из следующих действий:

  • Вы можете добавить дополнительную строку (y + 1) к макету, в котором в x-й ячейке содержится фиктивная JPanel, а в этой JPanel вы вызываете .setPreferredSize(new Dimension(desiredWidth, 0));.
  • То же самое, но вместо установки предпочитаемого размера вы устанавливаете вставки для объекта GridBagConstraints, используемого при добавлении этой фиктивной панели. Поэтому, если вам нужна фиксированная ширина, просто наберите gbc.insets = new Insets(0,preferredWidth,0,0); или gbc.insets = new Insets(0,0,0,preferredWidth);. Таким образом, сама панель имеет размер (0,0), но содержащая ячейка будет вынуждена быть настолько широкой, насколько вы укажете (потому что вставки - это внешний отступ, видимый из компонента).

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

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

Это решение работает, учитывая, что ширина JLabel не будет превышать desiredWidth, потому что в этом случае ячейка также будет расти. Чтобы решить эту проблему, вы всегда можете указать максимальный размер JLabel (здесь у вас нет проблемы неизвестных высот - для максимальной высоты вы можете использовать Integer.MAX_VALUE).

Та же история касается высоты, просто введите фиктивный столбец и добавьте фиктивную JPanel с размерностью = (0, предпочитаемый высотой) в ячейку в строке, где возникает проблема.

Недостаток этого подхода: вы должны использовать фиктивные компоненты, что никогда не было лучшим способом, но здесь он работает довольно хорошо.

4 голосов
/ 27 июля 2011

для лучшего и простого вывода в графический интерфейс лучше искать Borderlayout,

JPanel#setPrefferedSize(200, 30); для JButton с Icon и JLabel на WEST area

JPanel#setPrefferedSize(200, 30); (правая панель) до EAST area

положить другой JPanel на CENTER area

...