2014-10-24 5 views
1

Я создаю базовый пользовательский интерфейс в Swing и надеялся на некоторую помощь. Ниже приведен скриншот того, что я пытаюсь достичь:Java Swing UI Layout

enter image description here

Мой код в настоящее время выглядит следующим образом:

package testui; 

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

public class TestUI{ 

    private JTextField outputArea = new JTextField(); 
    private JTextField errorReportArea = new JTextField(); 

    private JPanel inputPanel = new JPanel(); 

    private JLabel nameLabel = new JLabel("Item Name"); 
    private JLabel numberLabel = new JLabel("Number of units (or Volume in L)"); 
    private JLabel priceLabel = new JLabel("Price per unit (Or L) in pence"); 

    private JTextField nameField = new JTextField(10); 
    private JTextField numberField = new JTextField(10); 
    private JTextField priceField = new JTextField(10); 

    private JButton addVolumeButton = new JButton("Add by Volume"); 
    private JButton addNumberButton = new JButton("Add by number of units");   

    public TestUI() { 
     JFrame frame = new JFrame("Fuel Station"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     outputArea.setEditable(false); 
     errorReportArea.setEditable(false); 

     inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS)); 
     inputPanel.add(nameLabel); 
     inputPanel.add(nameField); 
     inputPanel.add(numberLabel); 
     inputPanel.add(numberField); 
     inputPanel.add(priceLabel); 
     inputPanel.add(priceField); 
     inputPanel.add(addVolumeButton); 
     inputPanel.add(addNumberButton); 

     Container contentPane = frame.getContentPane(); 
     contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); 
     contentPane.add(outputArea); 
     contentPane.add(errorReportArea); 
     contentPane.add(inputPanel); 

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

    public static void main(String[] args) { 
     TestUI test1 = new TestUI(); 
    } 

} 

который выглядит следующим образом:

enter image description here

Так то, что я хотел бы сделать, это установить определенный размер для двух верхних JTextFields, поскольку верхний будет содержать несколько строк текст, а один ниже будет содержать только одну строку текста. Я не уверен, как это сделать, не используя setSize, так как мне сказали, что это неправильная практика кодирования, чтобы использовать это.

Я также хотел бы добавить некоторые дополнения между JLabels, JTextFields и JButtons в нижней JPanel.

Если кто-то может дать мне некоторые предложения по изменения размера этих компонентов я был бы весьма признателен

ответ

2
  • Поскольку вы хотите, чтобы ваши текстовые поля были многострочными, используйте JTextAreas. JTextFields только однолистные.
  • Ваши компоненты находятся рядом друг с другом, что не похоже на ваш предполагаемый результат. Может быть какой-то метод, который дает вашим компонентам некоторую комнату для передышки, прежде чем вы позвоните frame.pack()
  • Ищите какой-либо метод, который может сделать компонент, заполнить общее количество комнаты, которое он дал; особенно когда вы хотите что-то заполнить большой кусок пространства.
  • Вы можете установить количество столбцов вместо setSize() для вашего JTextFields/JTextAreas. Просто говорю.
  • Обзор всех Java's Layout Managers поможет вам получить представление о возможностях и случаи использования для каждого менеджера компоновки
+2

+1 для области текста. Но, пожалуйста, вытащите _ "remove frame.pack()" _. Рамка должна быть упакована. Использование BorderLayout вместе с подсказками в строке/столбце текстовой области должно обеспечить OP то, что они хотят –

+0

* исправлено. Я думаю, что в большинстве случаев вы должны использовать 'frame.pack()' просто так, чтобы у вас не было пустой комнаты. – Luminous

+0

Спасибо за ваш совет, я изменил первое текстовое поле на текстовое поле и использовал outputArea.setRows (30), чтобы установить его размер. Посмотрев на менеджеров компоновки, я также изменил boxlayout моей нижней панели на FlowLayout, который хорошо работает и также включает посылку по 5 пикселей по компонентам по умолчанию – user3371750

0

Есть несколько менеджеров компоновки, которые являются достаточно гибкими, чтобы выполнить это, например, Mig, GridBag и SpringLayout.

В вашем случае, вы должны были бы следующие ограничения:

outputarea - south границы ограничивается до ### точек с северной границы contentPane

errorReportArea - границы north ограничивается до 0px от outputarea юг и south граница ограничена 0px от inputPanel к северу.

inputPanel - north граница ограничена быть ## px с южной границы contentPane.

Разработчики GUI, такие как WindowBuilder, позволят вам сделать это довольно быстро. Вы просто отбрасываете макет на contentPane, а затем устанавливаете ограничения.

+0

Спасибо за ваши предложения, к сожалению, мы изучали только качаться на я, конечно, затея, поэтому это все, что нам разрешено использовать – user3371750

+0

@ user3371750 [javax.swing.SpringLayout] (http://docs.oracle.com/javase/7/docs/api/javax/swing/SpringLayout.html) является частью Swing: – Compass

0

Если вы должны использовать макет коробки взглянуть на методы клея и rigidArea в Box. Если вы можете использовать другие макеты, перейдите к тем, которые предлагаются другими ответами.

0

Я создал решение с менеджером MigLayout.

Вот некоторые рекомендации:

  • Put код приложения вне конструктора; в решении код помещается в метод initUI().
  • Приложение должно быть запущено по EDT, позвонив по телефону EventQueue.invokeLater(). (См. Метод main() предоставленного решения.)
  • Используйте современный гибкий менеджер макета: MigLayout, GroupLayout, или FormLayout. Потратьте некоторое время, чтобы изучить их, чтобы полностью понять процесс управления макетами. Это важно, чтобы иметь хорошее понимание этой темы.
  • Сократить этикетки; используйте более дескриптивные подсказки .
package com.zetcode; 

import java.awt.EventQueue; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 
import net.miginfocom.swing.MigLayout; 

public class MigLayoutSolution extends JFrame { 

    private JTextArea outputArea; 
    private JTextField errorReportField; 

    private JLabel nameLabel; 
    private JLabel numberLabel; 
    private JLabel priceLabel; 

    private JTextField nameField; 
    private JTextField numberField; 
    private JTextField priceField; 

    private JButton addVolumeButton; 
    private JButton addNumberButton; 

    public MigLayoutSolution() { 

     initUI(); 
    } 

    private void initUI() { 

     setLayout(new MigLayout()); 

     outputArea = new JTextArea(10, 20); 
     errorReportField = new JTextField(15); 

     nameLabel = new JLabel("Item name"); 
     numberLabel = new JLabel("# of units"); 
     numberLabel.setToolTipText("Number of units (or Volume in L)"); 
     priceLabel = new JLabel("Price per unit"); 
     priceLabel.setToolTipText("Price per unit (Or L) in pence"); 
     nameField = new JTextField(10); 
     numberField = new JTextField(10); 
     priceField = new JTextField(10); 

     addVolumeButton = new JButton("AddVol"); 
     addVolumeButton.setToolTipText("Add by Volume"); 
     addNumberButton = new JButton("AddNum"); 
     addNumberButton.setToolTipText("Add by number of units"); 

     add(new JScrollPane(outputArea), "grow, push, wrap"); 
     add(errorReportField, "growx, wrap"); 
     add(nameLabel, "split"); 
     add(nameField); 
     add(numberLabel); 
     add(numberField); 
     add(priceLabel); 
     add(priceField); 
     add(addVolumeButton); 
     add(addNumberButton); 

     pack(); 

     setTitle("Fuel station"); 
     setLocationRelativeTo(null); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public static void main(String[] args) { 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       MigLayoutSolution ex = new MigLayoutSolution(); 
       ex.setVisible(true); 
      } 
     }); 
    } 
} 

enter image description here