如何在JFrame中正确添加多个JLabel与JTextField?
问题
开发基于Swing的三角形面积计算器,要求用户输入三边长度,通过海伦公式计算面积。已定义JLabel与JTextField变量,但仅“Side c”对应的组件能在JFrame中显示,其余组件无法正常显示。
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.text.DecimalFormat; /** * Calculate the area of a triangle first finding the sides then using Heron's Formula * @author Chris Condreay */ public class TriangleCalculator extends JPanel { /* Instance Variables */ private JButton calcButton; private JTextField sideAField; private JTextField sideBField; private JTextField sideCField; private JLabel triangleAreaLabel; /* Constructor */ public TriangleCalculator() { this.calcButton = new JButton("Calculate"); this.sideAField = new JTextField(10); this.sideBField = new JTextField(10); this.sideCField = new JTextField(10); this.triangleAreaLabel = new JLabel("Triangle Area: "); /* Setup listeners */ ActionListener myListener = new TriangleListener(); this.calcButton.addActionListener(myListener); this.sideAField.addActionListener(myListener); this.sideBField.addActionListener(myListener); this.sideCField.addActionListener(myListener); /* Sides Entry Panel */ JPanel sideAEntryPanel = new JPanel(); JPanel sideBEntryPanel = new JPanel(); JPanel sideCEntryPanel = new JPanel(); // sideAEntryPanel.setLayout(new BoxLayout(sideAEntryPanel, BoxLayout.X_AXIS)); // sideBEntryPanel.setLayout(new BoxLayout(sideBEntryPanel, BoxLayout.X_AXIS)); // sideCEntryPanel.setLayout(new BoxLayout(sideCEntryPanel, BoxLayout.X_AXIS)); JLabel sideATagLabel = new JLabel("Side a: "); JLabel sideBTagLabel = new JLabel("Side b: "); JLabel sideCTagLabel = new JLabel("Side c: "); sideAEntryPanel.add(sideATagLabel); sideBEntryPanel.add(sideBTagLabel); sideCEntryPanel.add(sideCTagLabel); sideAEntryPanel.add(sideAField); sideBEntryPanel.add(sideBField); sideCEntryPanel.add(sideCField); /* Sides Panel */ JPanel resultSubPanel = new JPanel(); resultSubPanel.setLayout(new BoxLayout(resultSubPanel, BoxLayout.X_AXIS)); resultSubPanel.add(triangleAreaLabel); /* Setup top-level panel */ setPreferredSize(new Dimension(400, 150)); setLayout(new BorderLayout()); add(this.calcButton, BorderLayout.EAST); add(sideAEntryPanel, BorderLayout.WEST); add(sideBEntryPanel, BorderLayout.WEST); add(sideCEntryPanel, BorderLayout.WEST); add(resultSubPanel, BorderLayout.SOUTH); } private void updateCalculation(double a, double b, double c) { double trianglePerimeter = a + b + c; double triangleSide = trianglePerimeter / 2; double triangleArea = Math.sqrt(triangleSide * (triangleSide - a) * (triangleSide - b) * (triangleSide - c)); DecimalFormat myFormat = new DecimalFormat("#,###,###.###"); triangleAreaLabel.setText("Volume: " + myFormat.format(triangleArea)); } /* Button listener */ private class TriangleListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { String userSideA = sideAField.getText(); String userSideB = sideBField.getText(); String userSideC = sideCField.getText(); try { double a = Double.parseDouble(userSideA); double b = Double.parseDouble(userSideB); double c = Double.parseDouble(userSideC); if (a < 0 ) { JOptionPane.showMessageDialog(null, "Please enter positive values only!"); sideAField.setText(""); } else if (b < 0) { JOptionPane.showMessageDialog(null, "Please enter positive values only!"); sideBField.setText(""); } else if (c < 0) { JOptionPane.showMessageDialog(null, "Please enter positive values only!"); sideCField.setText(""); } else { updateCalculation(a, b, c); } } catch (NumberFormatException err) { JOptionPane.showMessageDialog(null, "Please enter numbers only!"); sideAField.setText(""); sideBField.setText(""); sideCField.setText(""); } } } /* Main Method */ public static void main(String[] args) { JFrame myFrame = new JFrame("Triangle Calculator - Chris Condreay"); myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); /* Add a panel to the frame */ JPanel myPanel = new TriangleCalculator(); myFrame.getContentPane().add(myPanel); myFrame.pack(); myFrame.setVisible(true); } }

解决方案
核心问题原因
BorderLayout的每个方位(如WEST、EAST)仅能容纳一个组件。你连续三次调用add(xxx, BorderLayout.WEST),后续添加的组件会直接覆盖之前的,最终只有最后添加的sideCEntryPanel能显示。
修复步骤
- 合并侧边输入组件:创建一个垂直布局的面板,将三个输入面板(sideAEntryPanel、sideBEntryPanel、sideCEntryPanel)加入其中,再将这个组合面板放到BorderLayout的WEST区域。
- 修正文本错误:
updateCalculation方法中把显示文本从"Volume"改为"Triangle Area",避免概念混淆。 - 补充合法性验证:添加三角不等式检查,确保输入的三边能构成有效三角形。
修改后的完整代码
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.text.DecimalFormat; /** * Calculate the area of a triangle first finding the sides then using Heron's Formula * @author Chris Condreay */ public class TriangleCalculator extends JPanel { /* Instance Variables */ private JButton calcButton; private JTextField sideAField; private JTextField sideBField; private JTextField sideCField; private JLabel triangleAreaLabel; /* Constructor */ public TriangleCalculator() { this.calcButton = new JButton("Calculate"); this.sideAField = new JTextField(10); this.sideBField = new JTextField(10); this.sideCField = new JTextField(10); this.triangleAreaLabel = new JLabel("Triangle Area: "); /* Setup listeners */ ActionListener myListener = new TriangleListener(); this.calcButton.addActionListener(myListener); this.sideAField.addActionListener(myListener); this.sideBField.addActionListener(myListener); this.sideCField.addActionListener(myListener); /* Sides Entry Panel */ JPanel sideAEntryPanel = new JPanel(); JPanel sideBEntryPanel = new JPanel(); JPanel sideCEntryPanel = new JPanel(); JLabel sideATagLabel = new JLabel("Side a: "); JLabel sideBTagLabel = new JLabel("Side b: "); JLabel sideCTagLabel = new JLabel("Side c: "); sideAEntryPanel.add(sideATagLabel); sideBEntryPanel.add(sideBTagLabel); sideCEntryPanel.add(sideCTagLabel); sideAEntryPanel.add(sideAField); sideBEntryPanel.add(sideBField); sideCEntryPanel.add(sideCField); // 新增:创建垂直面板容纳三个输入组件 JPanel westPanel = new JPanel(); westPanel.setLayout(new BoxLayout(westPanel, BoxLayout.Y_AXIS)); westPanel.add(sideAEntryPanel); westPanel.add(sideBEntryPanel); westPanel.add(sideCEntryPanel); /* Sides Panel */ JPanel resultSubPanel = new JPanel(); resultSubPanel.setLayout(new BoxLayout(resultSubPanel, BoxLayout.X_AXIS)); resultSubPanel.add(triangleAreaLabel); /* Setup top-level panel */ setPreferredSize(new Dimension(400, 150)); setLayout(new BorderLayout()); add(this.calcButton, BorderLayout.EAST); // 将组合后的westPanel添加到WEST区域 add(westPanel, BorderLayout.WEST); add(resultSubPanel, BorderLayout.SOUTH); } private void updateCalculation(double a, double b, double c) { double trianglePerimeter = a + b + c; double triangleSide = trianglePerimeter / 2; double triangleArea = Math.sqrt(triangleSide * (triangleSide - a) * (triangleSide - b) * (triangleSide - c)); DecimalFormat myFormat = new DecimalFormat("#,###,###.###"); // 修正文本:从Volume改为Triangle Area triangleAreaLabel.setText("Triangle Area: " + myFormat.format(triangleArea)); } /* Button listener */ private class TriangleListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { String userSideA = sideAField.getText(); String userSideB = sideBField.getText(); String userSideC = sideCField.getText(); try { double a = Double.parseDouble(userSideA); double b = Double.parseDouble(userSideB); double c = Double.parseDouble(userSideC); if (a <= 0 || b <= 0 || c <= 0) { JOptionPane.showMessageDialog(null, "请输入正数!"); sideAField.setText(""); sideBField.setText(""); sideCField.setText(""); } // 新增:验证三边能否构成三角形 else if (a + b <= c || a + c <= b || b + c <= a) { JOptionPane.showMessageDialog(null, "输入的三边无法构成有效三角形!"); sideAField.setText(""); sideBField.setText(""); sideCField.setText(""); } else { updateCalculation(a, b, c); } } catch (NumberFormatException err) { JOptionPane.showMessageDialog(null, "请输入有效的数字!"); sideAField.setText(""); sideBField.setText(""); sideCField.setText(""); } } } /* Main Method */ public static void main(String[] args) { JFrame myFrame = new JFrame("Triangle Calculator - Chris Condreay"); myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); /* Add a panel to the frame */ JPanel myPanel = new TriangleCalculator(); myFrame.getContentPane().add(myPanel); myFrame.pack(); myFrame.setVisible(true); } }
内容的提问来源于stack exchange,提问作者chriscondreay
相关产品推荐
相关产品推荐

