2016-10-02 1 views
1

enter image description hereКак я поставил метку под радио-кнопки в панели с Java Swing/AWT

Существует 3 панели, которые я создал, как показано на рисунке. Первая панель - панель «От», вторая - панель «Кому», а третья панель кнопок. Итак, вопрос в том, как я могу поместить новую строку для «Enter Temperature: []», чтобы она была под клавишами? Я очень новичок в Java swing/awt, пожалуйста, несите меня.

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

public class TemperatureConversion extends JFrame{ 

// component 
JTextField txtFromTemp, txtToTemp; 
JLabel lblFromTemp, lblToTemp; 
JRadioButton radFromCelsius, radFromFahrenheit, radFromKelvin; 
JRadioButton radToCelsius, radToFahrenheit, radToKelvin;  
JPanel pnlFromRadioButton, pnlToRadioButton, pnlFromTemp, pnlButton; 
ButtonGroup bgFrom, bgTo; 
JButton btnConvert, btnExit; 

// constructor 
public TemperatureConversion(){ 
    super("Temperature"); 

    // assign objects 
    radFromCelsius = new JRadioButton("Celsius", true); 
    radFromFahrenheit = new JRadioButton("Fahrenheit"); 
    radFromKelvin = new JRadioButton("Kelvin"); 
    lblFromTemp = new JLabel("Enter Temperature: "); 
    pnlFromTemp = new JPanel(); 
    btnConvert = new JButton("Convert"); 
    btnExit = new JButton("Exit"); 
    pnlButton = new JPanel(); 
    txtFromTemp = new JTextField(3); 
    lblToTemp = new JLabel("Comparable Temperature: "); 
    txtToTemp = new JTextField(3); 


    // register the button to a listener 
    btnExit.addActionListener(new MyButtonListener()); 
    btnConvert.addActionListener(new MyButtonListener()); 


    // make the multiple choice exclusive but not a container 
    bgFrom = new ButtonGroup(); 
    bgFrom.add(radFromCelsius); 
    bgFrom.add(radFromFahrenheit); 
    bgFrom.add(radFromKelvin); 

    // radio buttons 
    radToCelsius = new JRadioButton("Celsius"); 
    radToFahrenheit = new JRadioButton("Fahrenheit", true); 
    radToKelvin = new JRadioButton("Kelvin"); 

    // make the multiple choice exclusive 
    bgTo = new ButtonGroup(); 
    bgTo.add(radToCelsius); 
    bgTo.add(radToFahrenheit); 
    bgTo.add(radToKelvin); 


    pnlFromRadioButton = new JPanel(); 
    pnlToRadioButton = new JPanel(); 

    // decorate the panel 
    pnlFromRadioButton.setBorder(BorderFactory.createTitledBorder("From")); 
    pnlToRadioButton.setBorder(BorderFactory.createTitledBorder("To")); 

    // add radiobutton to panel 
    pnlFromRadioButton.add(radFromCelsius); 
    pnlFromRadioButton.add(radFromFahrenheit); 
    pnlFromRadioButton.add(radFromKelvin); 
    pnlToRadioButton.add(radToCelsius); 
    pnlToRadioButton.add(radToFahrenheit); 
    pnlToRadioButton.add(radToKelvin); 

    // add button to panel 
    pnlButton.add(btnConvert); 
    pnlButton.add(btnExit); 

    // add label and txt field to panel 
    pnlFromRadioButton.add(lblFromTemp); 
    pnlFromRadioButton.add(txtFromTemp); 
    pnlToRadioButton.add(lblToTemp); 
    txtToTemp.setEditable(false); 
    pnlToRadioButton.add(txtToTemp); 


    // add panels to the frame 
    add(pnlFromRadioButton, BorderLayout.NORTH); 
    add(pnlToRadioButton, BorderLayout.CENTER); 
    add(pnlButton, BorderLayout.SOUTH); 


    setVisible(true); 
    setSize(400, 300); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    pack(); 
} 


// private inner class to handle button event 
private class MyButtonListener implements ActionListener { 
    // must override actionPerformed method 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (e.getSource() == btnConvert) { 
      if (radFromCelsius.isSelected()) 
      System.out.print("exit"); 
     } else if (e.getSource() == btnExit) { 
      System.exit(0); 
     } 
    } 
} 


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

} 
+0

Вы хотите, чтобы 'Enter Temperature: []' отображались под кнопками From? – c0der

+0

Да @ c0der. Я хочу это для этого, а также сопоставимую температуру: [] для отображения под кнопками «Кому». – Ojouk

ответ

2

Nest больше JPanels и использовать менеджеры компоновки

Например, в JPanel, где вы хотите две линии, придать ему BoxLayout ориентированы вдоль BoxLayout.PAGE_AXIS, а затем добавить еще два JPanels этого BoxLayout-используя , верхний JPanel с переключателями и нижней JPanel с JLabel и JTextField (или что-то еще, что вы хотите в нем).

Замечание: это было бы отличное место для использования перечисления, называемого TempScale, которое имело три значения: CELSIUS, FAHRENHEIT, KELVIN. Вы даже можете перечислить формулы для конверсии в Кельвин и обратно.

Например:

import java.awt.Component; 
import java.awt.event.*; 
import java.util.HashMap; 
import java.util.Map; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class TempConversion2 extends JPanel { 
    private ToFromPanel fromPanel = new ToFromPanel("From", true); 
    private ToFromPanel toPanel = new ToFromPanel("To", false); 
    private ButtonPanel buttonPanel = new ButtonPanel(fromPanel, toPanel); 

    public TempConversion2() { 
     setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 
     add(fromPanel); 
     add(toPanel); 
     add(buttonPanel); 
    } 

    private static void createAndShowGui() { 
     TempConversion2 mainPanel = new TempConversion2(); 

     JFrame frame = new JFrame("Temp Convert"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 

@SuppressWarnings("serial") 
class ButtonPanel extends JPanel { 

    public ButtonPanel(ToFromPanel fromPanel, ToFromPanel toPanel) { 
     add(new JButton(new ConvertAction("Convert", fromPanel, toPanel))); 
     add(new JButton(new ExitAction("Exit", KeyEvent.VK_X))); 
    } 

} 

@SuppressWarnings("serial") 
class ConvertAction extends AbstractAction { 
    private ToFromPanel fromPanel; 
    private ToFromPanel toPanel; 

    public ConvertAction(String name, ToFromPanel fromPanel, ToFromPanel toPanel) { 
     super(name); 
     int mnemonic = (int) name.charAt(0); 
     putValue(MNEMONIC_KEY, mnemonic); 
     this.fromPanel = fromPanel; 
     this.toPanel = toPanel; 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     String text = fromPanel.getText(); 
     try { 
      double fromTemp = Double.parseDouble(text.trim()); 
      TempScale fromScale = fromPanel.getTempScalesPanel().getSelectedTempScale(); 
      double kelvinValue = fromScale.convertToKelvin(fromTemp); 

      TempScale toScale = toPanel.getTempScalesPanel().getSelectedTempScale(); 
      double toValue = toScale.convertFromKelvin(kelvinValue); 

      String toValueString = String.format("%.2f", toValue); 
      toPanel.setText(toValueString); 
     } catch (NumberFormatException e1) { 
      Component parentComponent = fromPanel; 
      String message = "Text must be a valid number: " + text; 
      String title = "Invalid Text Entered"; 
      int messageType = JOptionPane.ERROR_MESSAGE; 
      JOptionPane.showMessageDialog(parentComponent, message, title, messageType); 
      fromPanel.setText(""); 
     } 
    } 
} 

@SuppressWarnings("serial") 
class ExitAction extends AbstractAction { 
    public ExitAction(String name, int mnemonic) { 
     super(name); 
     putValue(MNEMONIC_KEY, mnemonic); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.exit(0); 
    } 
} 

@SuppressWarnings("serial") 
class ToFromPanel extends JPanel { 
    private String title; 
    private TempScalesPanel tempScalesPanel = new TempScalesPanel(); 
    private JTextField tempTextField = new JTextField(3); 

    public ToFromPanel(String title, boolean textFieldEnabled) { 
     this.title = title; 
     tempTextField.setFocusable(textFieldEnabled); 

     JPanel bottomPanel = new JPanel(); 
     bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS)); 
     bottomPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); 
     bottomPanel.add(new JLabel("Temperature:")); 
     bottomPanel.add(Box.createHorizontalStrut(8)); 
     bottomPanel.add(tempTextField); 

     setBorder(BorderFactory.createTitledBorder(title)); 
     setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 
     add(tempScalesPanel); 
     add(bottomPanel); 
    } 

    public String getTitle() { 
     return title; 
    } 

    public TempScalesPanel getTempScalesPanel() { 
     return tempScalesPanel; 
    } 

    public String getText() { 
     return tempTextField.getText(); 
    } 

    public void setText(String text) { 
     tempTextField.setText(text); 
    } 
} 

@SuppressWarnings("serial") 
class TempScalesPanel extends JPanel { 
    private ButtonGroup buttonGroup = new ButtonGroup(); 
    private Map<ButtonModel, TempScale> buttonTempMap = new HashMap<>(); 

    public TempScalesPanel() { 
     for (TempScale tempScale : TempScale.values()) { 
      JRadioButton radioButton = new JRadioButton(tempScale.getName()); 
      add(radioButton); 
      buttonGroup.add(radioButton); 
      buttonTempMap.put(radioButton.getModel(), tempScale); 
      // set first button as selected by default 
      if (buttonGroup.getSelection() == null) { 
       buttonGroup.setSelected(radioButton.getModel(), true); 
      } 
     } 
    } 

    public TempScale getSelectedTempScale() { 
     ButtonModel model = buttonGroup.getSelection(); 
     return buttonTempMap.get(model); 
    } 
} 

Это перечисление, что я говорил. Обратите внимание: если вы измените enum и, например, добавите еще один элемент температурной шкалы, программа автоматически включит его в графический интерфейс и в вычислениях. Бог я люблю Яву и ООП.

public enum TempScale { 
    CELSIUS("Celsius", 1.0, -273.15), 
    FAHRENHEIT("Fahrenheit", 5.0/9.0, -459.67), 
    KELVIN("Kelvin", 1.0, 0.0); 

    private TempScale(String name, double ratioToKelvin, double absZero) { 
     this.name = name; 
     this.ratioToKelvin = ratioToKelvin; 
     this.absZero = absZero; 
    } 

    private String name; 
    private double ratioToKelvin; 
    private double absZero; 

    public String getName() { 
     return name; 
    } 

    public double getRatioToKelvin() { 
     return ratioToKelvin; 
    } 

    public double getAbsZero() { 
     return absZero; 
    } 

    public double convertToKelvin(double value) { 
     return (value - absZero) * ratioToKelvin; 
    } 

    public double convertFromKelvin(double kelvinValue) { 
     return (kelvinValue/ratioToKelvin) + absZero; 
    } 

} 
+0

Итак, из того, что я понимаю, создайте JPanel для контейнера From, а затем с JPanels, который у меня есть сейчас: pnlFromRadioButton создает другую панель pnlTextEnterTemperature, которые являются вложенными JPanels? 'code' pnlFrom.add (pnlFromRadioButton); pnlFrom.добавить (pnlTextEnterTemperature); – Ojouk

+0

@Ojouk: ваш из контейнера уже является JPanel. Создайте еще два - один для JRadioButtons и один для комбинации JLabel/JTextField. Например, см. Выше код, который также показывает использование перечисления при создании JPanels и при выполнении вычислений. –

2

Всегда рассматривайте отправку MCVE. Например, вы макет может быть упрощена и продемонстрировано:

import java.awt.BorderLayout; 
import java.awt.Label; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class TemperatureConversion extends JFrame{ 

    JPanel pnlFromRadioButton, pnlToRadioButton, pnlFromTemp, pnlButton; 

    // constructor 
    public TemperatureConversion(){ 

     pnlFromRadioButton = new JPanel(); 
     pnlFromRadioButton.add(new Label("From Panel")); 

     pnlToRadioButton = new JPanel(); 
     pnlToRadioButton.add(new Label("To Panel")); 

     pnlButton = new JPanel(); 
     pnlButton.add(new Label("Buttons Panel")); 

     // add panels to the frame 
     add(pnlFromRadioButton, BorderLayout.NORTH); 
     add(pnlToRadioButton, BorderLayout.CENTER); 
     add(pnlButton, BorderLayout.SOUTH); 

     setVisible(true); 
     setSize(400, 300); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

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

Предположим, что вы хотите на «Ввод температуры: []» ярлык, чтобы показать в другой «линии» под От кнопок, ваш конструктор изменится:

public TemperatureConversion(){ 

     //set a layout manger. You could use grid layout 
     //GridLayout gridLayout = new GridLayout(4, 1); 
     //Or BoxLayout 
     BoxLayout boxLayout = new BoxLayout(getContentPane(), BoxLayout.Y_AXIS); // top to bottom 
     setLayout(boxLayout); 
     pnlFromRadioButton = new JPanel(); 
     pnlFromRadioButton.add(new Label("From Panel")); 

     //create a panel to hold the desired label 
     pnlFromTemp = new JPanel(); 
     pnlFromTemp.add(new JLabel("Enter Temperature: [ ]"));//add label 

     pnlToRadioButton = new JPanel(); 
     pnlToRadioButton.add(new Label("To Panel")); 

     pnlButton = new JPanel(); 
     pnlButton.add(new Label("Buttons Panel")); 

     // add panels to the frame 
     //the panel will show in the order added 
     add(pnlFromRadioButton); 
     add(pnlFromTemp); 
     add(pnlToRadioButton); 
     add(pnlButton); 

     setVisible(true); 
     setSize(400, 300); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
0

к сожалению я новичок в форумах, и я не знаком с оприходования этикета для кодов @ c0der. Но использование GridLayout решило мою проблему, и я хочу показать вам, что я сделал, это большой беспорядок, но вот он. Вот мой странный код, но не знаю, как его уменьшить. Вот как это предполагают, чтобы выглядеть, как я хотел, и потому, что теперь я понимаю, что вы имеете в виду под «Гнездо более JPanel, и использовать менеджеры компоновки» @Hovercraft Насытившись Угри: my temperature program

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

public class TemperatureConversion extends JFrame { 

    // component 
    JTextField txtFromTemp, txtToTemp; 
    JLabel lblFromTemp, lblToTemp, lblToTempbox; 
    JRadioButton radFromCelsius, radFromFahrenheit, radFromKelvin; 
    JRadioButton radToCelsius, radToFahrenheit, radToKelvin; 
    JPanel pnlFromRadioButton, pnlToRadioButton, pnlFrom, pnlTo, pnlButton; 
    JPanel pnlEnterTemp, pnlComparableTemp; 
    ButtonGroup bgFrom, bgTo; 
    JButton btnConvert, btnExit; 

    // constructor 
    public TemperatureConversion() { 
    super("Temperature"); 

    // assign objects 
    radFromCelsius = new JRadioButton("Celsius", true); 
    radFromFahrenheit = new JRadioButton("Fahrenheit"); 
    radFromKelvin = new JRadioButton("Kelvin"); 
    lblFromTemp = new JLabel("Enter Temperature: "); 
    pnlFrom = new JPanel(); 
    btnConvert = new JButton("Convert"); 
    btnExit = new JButton("Exit"); 
    pnlButton = new JPanel(); 
    txtFromTemp = new JTextField(3); 
    lblToTemp = new JLabel("Comparable Temperature: "); 
    txtToTemp = new JTextField(3); 
    pnlTo = new JPanel(); 
    pnlEnterTemp = new JPanel(); 
    pnlComparableTemp = new JPanel(); 
    pnlFromRadioButton = new JPanel(); 
    pnlToRadioButton = new JPanel(); 

    // register the button to a listener 
    btnExit.addActionListener(new MyButtonListener()); 
    btnConvert.addActionListener(new MyButtonListener()); 

    // make the multiple choice exclusive but not a container 
    bgFrom = new ButtonGroup(); 
    bgFrom.add(radFromCelsius); 
    bgFrom.add(radFromFahrenheit); 
    bgFrom.add(radFromKelvin); 

    // radio buttons 
    radToCelsius = new JRadioButton("Celsius"); 
    radToFahrenheit = new JRadioButton("Fahrenheit", true); 
    radToKelvin = new JRadioButton("Kelvin"); 

    // make the multiple choice exclusive 
    bgTo = new ButtonGroup(); 
    bgTo.add(radToCelsius); 
    bgTo.add(radToFahrenheit); 
    bgTo.add(radToKelvin); 

    pnlFrom.setLayout(new GridLayout(2, 1)); 
    pnlFrom.add(pnlFromRadioButton); 
    pnlFrom.add(pnlEnterTemp); 

    pnlTo.setLayout(new GridLayout(2, 1)); 
    pnlTo.add(pnlToRadioButton); 
    pnlTo.add(pnlComparableTemp); 


    // decorate the panel 
    pnlFrom.setBorder(BorderFactory.createTitledBorder("From")); 
    pnlTo.setBorder(BorderFactory.createTitledBorder("To")); 

    // add radiobutton to panel 
    pnlFromRadioButton.add(radFromCelsius); 
    pnlFromRadioButton.add(radFromFahrenheit); 
    pnlFromRadioButton.add(radFromKelvin); 
    pnlToRadioButton.add(radToCelsius); 
    pnlToRadioButton.add(radToFahrenheit); 
    pnlToRadioButton.add(radToKelvin); 

    // add button to panel 
    pnlButton.add(btnConvert); 
    pnlButton.add(btnExit); 

    // add label and txt field to panel 
    pnlEnterTemp.add(lblFromTemp); 
    pnlEnterTemp.add(txtFromTemp); 
    pnlComparableTemp.add(lblToTemp); 
    txtToTemp.setEditable(false); 
    pnlComparableTemp.add(txtToTemp); 

    // add panels to the frame 
    add(pnlFrom, BorderLayout.NORTH); 
    add(pnlTo, BorderLayout.CENTER); 
    add(pnlButton, BorderLayout.SOUTH); 

    setVisible(true); 
    setSize(400, 300); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    pack(); 
    } 


    // private inner class to handle button event 
    private class MyButtonListener implements ActionListener { 
    // must override actionPerformed method 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (e.getSource() == btnConvert) { 
     if (radFromCelsius.isSelected() && radToFahrenheit.isSelected()) { 
      int strInput = Integer.parseInt(txtFromTemp.getText()); 
      int celsius = strInput * 9/5 + 32; 
      txtToTemp.setText(Integer.toString(celsius)); 
     } else if (radFromCelsius.isSelected() && radToCelsius.isSelected() || 
      radFromFahrenheit.isSelected() && radToFahrenheit.isSelected() || 
      radFromKelvin.isSelected() && radToKelvin.isSelected()) { 
     txtToTemp.setText(txtFromTemp.getText()); 
     } else if (radToCelsius.isSelected() && radFromFahrenheit.isSelected()) { 
      int strInput = Integer.parseInt(txtFromTemp.getText()); 
      int fahrenheit = (strInput - 32) * 5/9; 
      txtToTemp.setText(Integer.toString(fahrenheit)); 
     } else if (radFromKelvin.isSelected() && radToCelsius.isSelected()) { 
      double strInput = Integer.parseInt(txtFromTemp.getText()); 
      double celsius = strInput - 273.15; 
      txtToTemp.setText(Double.toString(celsius)); 
     } else if (radFromKelvin.isSelected() && radToFahrenheit.isSelected()) { 
      double strInput = Integer.parseInt(txtFromTemp.getText()); 
      double fahrenheit = strInput - 459.67; 
      txtToTemp.setText(Double.toString(fahrenheit)); 
     } else if (radFromCelsius.isSelected() && radToKelvin.isSelected()) { 
      double strInput = Integer.parseInt(txtFromTemp.getText()); 
      double celsius = strInput + 273.15; 
      txtToTemp.setText(Double.toString(celsius)); 
     } else if (radFromFahrenheit.isSelected() && radToKelvin.isSelected()) { 
      double strInput = Integer.parseInt(txtFromTemp.getText()); 
      double fahrenheit = strInput + 255.37; 
      txtToTemp.setText(Double.toString(fahrenheit)); 
     } 
     } else if (e.getSource() == btnExit) { 
     System.exit(0); 
     } 
    } 
    } 

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

Кстати @Hovercraft Full Из Eels ваше решение является более эффективным и продвинутым, чем мой уровень мышления. Я новичок в программировании вообще, так что медведь со мной на мой грязный код и организацию LOL. Я едва опустил ноги в ООП. У меня есть представление о том, как вы использовали перечисление для TempScale, и я благодарю вас за ваше предложение. Я сохраню их в своих заметках в качестве ссылок.

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