JLabel 文本在窄列中而不是展开

Posted

技术标签:

【中文标题】JLabel 文本在窄列中而不是展开【英文标题】:JLabel text in narrow column instead of spread out 【发布时间】:2015-01-16 12:53:47 【问题描述】:

我正在尝试制作一个带有 JLabel 的框架。我已成功将其添加到框架中,但文本显示在一个狭窄的列中,而不是在窗口中占用更多空间。我该如何解决?我尝试使用 html,但没有成功。

编辑:介绍面板是我遇到问题的面板。

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Window implements ActionListener

    JFrame frame = new JFrame("Loan Program");
    JFrame intro = new JFrame("Welcome To The Loan Program!");
    JPanel panel = new JPanel(new GridBagLayout());
    JPanel panel2 = new JPanel(new GridBagLayout());
    JPanel panel3 = new JPanel(new GridBagLayout());
    JPanel descriptionPanel = new JPanel(new GridBagLayout());
    JPanel descriptionPanel1 = new JPanel(new GridBagLayout());
    GridBagConstraints g = new GridBagConstraints();
    JButton calculate;
    JButton cancel;
    JButton reset;
    JButton introOk;
    JLabel loanAmount;
    JLabel loanInterest;
    JLabel loanPeriod;
    JLabel monthlyRepayment;
    JLabel introLabel;
    JTextField laField;
    JTextField liField;
    JTextField lpField;
    JTextField mrField;
    DecimalFormat df = new DecimalFormat("#.##");

    public Window() 

        g.insets = new Insets(10, 10, 20, 10); //For the spacing between elements


        //Initalizing components
        introLabel = new JLabel();
        introOk = new JButton("Ok");

        //Setting up text for intro panel
        String text = "<html><h1 align='center'>Loan Program 1.0</h1>";
        text = text + "This program lets you calculate the various aspects of loans <br />";
        text = text + "If you are leaving a field empty then use 0 for its place <br />";
        text = text + "<h1 align='center'>Text Fields To Enter</h1>";
        text = text + "Monthly Payment: Enter values for: Loan Period, Loan Amount, and Loan Interest. Enter 0 for Monthly Payment. <br />";
        text = text + "Loan Period: Enter Values for: Loan Amount, Loan Interest, and Monthly Payment. Enter 0 for Loan Period. <br />";

        //Setting text to the label
        introLabel.setText(text);

        //Positioning introLabel
        descriptionPanel.add(introLabel, g);


        //Positioning button
        descriptionPanel1.add(introOk, g);

        //Actionlistener for buttont to dipose current frame.
        introOk.addActionListener(new ActionListener() 
            @Override
            public void actionPerformed(ActionEvent e) 
                intro.dispose();

            
        );

        intro.add(descriptionPanel);
        intro.add(descriptionPanel1, BorderLayout.SOUTH);


        //Initializing buttons here and adding them to panel
        calculate = new JButton("Calculate");
        reset = new JButton("Reset");
        cancel = new JButton("Cancel"); 
        panel.add(calculate, g);
        panel.add(reset, g);
        panel.add(cancel, g);

        //Adding the Actionlistener for buttons
        calculate.addActionListener(this);
        reset.addActionListener(this);
        cancel.addActionListener(this);

        //Initializing the labels
        loanAmount = new JLabel("Loan Amount:");
        loanInterest = new JLabel("Loan Interest:");
        loanPeriod = new JLabel("Loan Period:");
        monthlyRepayment = new JLabel("Monthly Payment:");

        //Positioning loanAmount label
        g.gridx = 0;
        g.gridy = 0;
        panel2.add(loanAmount, g);

        //Positioning loanInterest label
        g.gridx = 0;
        g.gridy = 2;
        panel2.add(loanInterest, g);

        //Positioning loanPeriod label
        g.gridx = 0;
        g.gridy = 3;
        panel2.add(loanPeriod, g);

        //Positioning monthlyRepayment label
        g.gridx = 0;
        g.gridy = 4;
        panel2.add(monthlyRepayment, g);

        //Initializing the text fields
        laField = new JTextField("", 20);
        liField = new JTextField("", 20);
        lpField = new JTextField("", 20);
        mrField = new JTextField("", 20);

        //Positioning laField
        g.gridx = 1;
        g.gridy = 0;
        panel2.add(laField, g);

        //Positioning liField
        g.gridx = 1;
        g.gridy = 2;
        panel2.add(liField, g);

        //Positioning lpField
        g.gridx = 1;
        g.gridy = 3;
        panel2.add(lpField, g);

        //Positioning mrField
        g.gridx = 1;
        g.gridy = 4;
        panel2.add(mrField, g);

        //Adding panels to the frame using boarderlayout
        frame.add(panel, BorderLayout.SOUTH);
        frame.add(panel2, BorderLayout.WEST);

        // Creating the window
        frame.setSize(500, 500);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //popup window for intro 
        intro.setSize(500, 500);
        intro.setVisible(true);
        intro.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    

    @Override
    public void actionPerformed(ActionEvent e) 

        Object o = e.getSource();

        if(o == cancel) 

            //Initializing components for the window
            JFrame frame1 = new JFrame("Are you sure?");
            JPanel panel = new JPanel(new GridBagLayout());
            JPanel panel2 = new JPanel(new GridBagLayout());
            JLabel label = new JLabel("Are you sure you want to exit?");
            JButton yes = new JButton("Yes");
            JButton no = new JButton("No");

            //Positioning Label
            g.gridx = 0;
            g.gridy = 0;
            panel.add(label, g);

            //Positioning yes button
            g.gridx = 0;
            g.gridy = 0;
            g.gridwidth = 1;
            panel2.add(yes, g);

            //Positioning no button
            g.gridx = 1;
            g.gridy = 0;
            panel2.add(no, g);

            //Action to close program when yes is clicked
            yes.addActionListener(new ActionListener() 
                @Override
                public void actionPerformed(ActionEvent e) 
                    System.exit(0);
                

            );

            //Action to close current window if no is clicked
            no.addActionListener(new ActionListener() 

                @Override
                public void actionPerformed(ActionEvent e) 
                    frame1.dispose();
                

            );

            //Adding the panels to frame with borderlayout
            frame1.add(panel, BorderLayout.NORTH);
            frame1.add(panel2, BorderLayout.SOUTH);

            //Setting up frame 
            frame1.setSize(300, 300);
            frame1.setVisible(true);;
            frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            //Adding actionListener once again for second level of menu 
            //No to close the current window
            Object b = e.getSource();
            if(b == no) 
                System.out.println("heres");
                frame1.dispose();
             

            //Yes to close the program completely
            if(b == yes) 
                System.exit(0);
            

        

        //New instance of window to reset it
        if(o == reset) 
            frame.dispose();
            new Window();
        

        //Calculate buttons actions
        if(o == calculate) 

            //Test values to see if they are being passed
            System.out.println(laField.getText() + "\n" + liField.getText() + "/n" + lpField.getText() + "\n" + mrField.getText());

            //If statement for monthly payment with the correct fields filled out
            if(laField.getText() != null && liField.getText() != null && lpField.getText() != null && mrField.getText() == "0") 
                //Strings and double and ints to convert from text field number.
                String sRate, sMonths, sPrincipal;
                sRate = liField.getText();
                sMonths = lpField.getText();
                sPrincipal = laField.getText();
                double rate = Double.parseDouble(sRate);
                int months = Integer.parseInt(sMonths);
                double principal = Double.parseDouble(sPrincipal);

                //Setting up components for new window
                JFrame frame = new JFrame("Monthly Payment");
                JPanel panel = new JPanel(new GridBagLayout());
                JPanel panel2 = new JPanel(new GridBagLayout());
                JLabel label = new JLabel("The monthly payment is: " + df.format(calculateMonthlyRepayment(rate, months, principal)));
                JButton button = new JButton("Ok");

                //Action listener for okay button to just close current frame.
                button.addActionListener(new ActionListener() 
                    @Override
                    public void actionPerformed(ActionEvent e) 
                        frame.dispose();
                    

                );

                //Padding for element
                g.insets = new Insets(5, 5, 5, 5);

                //Adding components to panel
                panel.add(label, g);
                panel2.add(button, g);

                //Adding panels to frame
                frame.add(panel, BorderLayout.CENTER);
                frame.add(panel2, BorderLayout.SOUTH);

                //Intializing frame
                frame.setSize(300, 300);
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


            

            //If statement for period calculation checks to see proper fields filled
            if(mrField.getText() != null && liField.getText() != null && laField.getText() != null && lpField.getText() == "0"); 

                //String and doubles to convert to numbers from text box
                String sMonthlyPayment, sloanAmount, sinterestRate;
                sMonthlyPayment = mrField.getText();
                sloanAmount = laField.getText();
                sinterestRate = liField.getText();
                double monthlyPayment = Double.parseDouble(sMonthlyPayment);
                double loanAmount = Double.parseDouble(sloanAmount);
                double interestRate = Double.parseDouble(sinterestRate);

                //Initializing the components
                JFrame frame = new JFrame("Total Loan Period");
                JPanel panel = new JPanel(new GridBagLayout());
                JPanel panel2 = new JPanel(new GridBagLayout());
                JLabel label = new JLabel("Total number of periods is : " + calculatePeriod(monthlyPayment, interestRate, loanAmount));
                JButton button = new JButton("Ok");

                //Button listener to close current frame
                button.addActionListener(new ActionListener() 
                    @Override
                    public void actionPerformed(ActionEvent e) 
                        frame.dispose();
                    

                );

                //Padding for the components
                g.insets = new Insets(5, 5, 5, 5);

                //Adding componeents to panel with gridbag
                panel.add(label, g);
                panel2.add(button, g);

                //Adding panels to frame
                frame.add(panel, BorderLayout.CENTER);
                frame.add(panel2, BorderLayout.SOUTH);

                //Initializing the frame
                frame.setSize(300, 300);
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
        

    

    public double calculateMonthlyRepayment(double rate, int months, double principal) 
        String input = mrField.getText();
        double totalMr = Double.parseDouble(input);
        double mrpayment = (rate + ((rate)/((Math.pow(1 + rate, months) - 1)))) * principal;
        return mrpayment;
    

    double calculatePeriod(double monthlyPayment, double interestRate, double loanAmount) 
        return (Math.log(monthlyPayment) - Math.log(monthlyPayment - (loanAmount * interestRate))) / Math.log(1 + interestRate);
    


【问题讨论】:

您必须在组件上使用 setPreferredSize() 设置大小,并在 setVisible(true) 之前调用 pack() @gantners: Don't use setPreferredSize() when you really mean to override getPreferredSize(). @trashgod 你是对的,懒惰的我...... 【参考方案1】:

首先,推荐一个,请尝试使用像 window builder 或 matisse 这样的 gui 设计器。它们确实减轻了您的日常工作,并限制了定义布局约束的代码。

如果您在布局和未出现或未对齐的组件方面遇到问题,这通常表明您对所需布局管理器的使用有误。在整个 *** 中都有关于它的优秀帖子。

代码中最严重的错误是重用了 GridBagConstraints,这是一个 bad idea,因为

正如您可能从上面的示例中猜到的那样,可以为多个组件重用相同的 GridBagConstraints 实例,即使这些组件具有不同的约束。但是,建议您不要重复使用 GridBagConstraints,因为如果您忘记为每个新实例重置字段,这很容易导致您引入细微的错误。

因此,只有在每个组件的约束相同时才尝试共享您的约束,例如标签的约束和文本字段列的另一个约束。

您的错误也存在于窄列上。如果您还想为所有标签指定所需的宽度,请在标签约束上设置网格宽度。这也适用于文本字段约束。

再次查看 GridBagLayout Example,以更好地了解其用法。

更多建议: 将您的类命名为 Window 可能会误导其他人,因为他们可能会认为他们正在使用 java.awt.window,这与您的类完全不同,并且您只能在 import 语句中看到它。

任何 gui 元素都必须从 EDT 调用,因此请使用 SwingUtilities 调用您的类,例如

SwingUtilities.invokeLater(new Runnable() 
    public void run() 
        new Window();
    
);

别忘了打电话给pack(),让布局管理器根据您的约束条件完成工作。

也尽量避免使用大量的框架,而是使用对话框。只有在需要将它们放在单独的上下文中时才应该使用框架,就像它们完全独立一样。

举个例子:

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.BorderLayout;

import javax.swing.JPanel;

import java.awt.GridBagConstraints;
import java.awt.Insets;

import javax.swing.JTextField;
import javax.swing.JButton;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class GridExample extends JFrame
    public GridExample() 
        initComponents();
        pack();
        setTitle("GridExample");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null); //Center, could also be setLocationByPlatform(true);
    

    @Override
    public Dimension preferredSize() 
        return new Dimension(500,300);
    

    private void initComponents() 
        getContentPane().setLayout(new BorderLayout(0, 0));

        JPanel mainPanel = new JPanel();
        getContentPane().add(mainPanel, BorderLayout.CENTER);
        GridBagLayout gbl_mainPanel = new GridBagLayout();
        gbl_mainPanel.columnWidths = new int[]0, 0, 0, 0;
        gbl_mainPanel.rowHeights = new int[]0, 0, 0, 0, 0, 0;
        gbl_mainPanel.columnWeights = new double[]0.0, 1.0, 0.0, Double.MIN_VALUE;
        gbl_mainPanel.rowWeights = new double[]0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE;
        mainPanel.setLayout(gbl_mainPanel);

        JLabel lblLoanAmount = new JLabel("Loan Amount:");
        GridBagConstraints gbc_lblLoanAmount = new GridBagConstraints();
        gbc_lblLoanAmount.fill = GridBagConstraints.HORIZONTAL;
        gbc_lblLoanAmount.insets = new Insets(0, 0, 5, 5);
        gbc_lblLoanAmount.gridx = 0;
        gbc_lblLoanAmount.gridy = 0;
        mainPanel.add(lblLoanAmount, gbc_lblLoanAmount);

        txtLoanAmount = new JTextField();
        GridBagConstraints gbc_txtLoanAmount = new GridBagConstraints();
        gbc_txtLoanAmount.gridwidth = 2;
        gbc_txtLoanAmount.insets = new Insets(0, 0, 5, 0);
        gbc_txtLoanAmount.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtLoanAmount.gridx = 1;
        gbc_txtLoanAmount.gridy = 0;
        mainPanel.add(txtLoanAmount, gbc_txtLoanAmount);
        txtLoanAmount.setColumns(10);

        JLabel lblLoanInterest = new JLabel("Loan Interest:");
        GridBagConstraints gbc_lblLoanInterest = new GridBagConstraints();
        gbc_lblLoanInterest.insets = new Insets(0, 0, 5, 5);
        gbc_lblLoanInterest.fill = GridBagConstraints.BOTH;
        gbc_lblLoanInterest.gridx = 0;
        gbc_lblLoanInterest.gridy = 1;
        mainPanel.add(lblLoanInterest, gbc_lblLoanInterest);

        txtLoanInterest = new JTextField();
        GridBagConstraints gbc_txtLoanInterest = new GridBagConstraints();
        gbc_txtLoanInterest.gridwidth = 2;
        gbc_txtLoanInterest.anchor = GridBagConstraints.NORTH;
        gbc_txtLoanInterest.insets = new Insets(0, 0, 5, 0);
        gbc_txtLoanInterest.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtLoanInterest.gridx = 1;
        gbc_txtLoanInterest.gridy = 1;
        mainPanel.add(txtLoanInterest, gbc_txtLoanInterest);
        txtLoanInterest.setColumns(10);

        JLabel lblLoanPeriod = new JLabel("Loan Period:");
        GridBagConstraints gbc_lblLoanPeriod = new GridBagConstraints();
        gbc_lblLoanPeriod.fill = GridBagConstraints.HORIZONTAL;
        gbc_lblLoanPeriod.insets = new Insets(0, 0, 5, 5);
        gbc_lblLoanPeriod.gridx = 0;
        gbc_lblLoanPeriod.gridy = 2;
        mainPanel.add(lblLoanPeriod, gbc_lblLoanPeriod);

        txtLoanPeriod = new JTextField();
        GridBagConstraints gbc_txtLoanPeriod = new GridBagConstraints();
        gbc_txtLoanPeriod.gridwidth = 2;
        gbc_txtLoanPeriod.anchor = GridBagConstraints.NORTH;
        gbc_txtLoanPeriod.insets = new Insets(0, 0, 5, 0);
        gbc_txtLoanPeriod.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtLoanPeriod.gridx = 1;
        gbc_txtLoanPeriod.gridy = 2;
        mainPanel.add(txtLoanPeriod, gbc_txtLoanPeriod);
        txtLoanPeriod.setColumns(10);

        JLabel lblMonthlyPayment = new JLabel("Monthly Payment:");
        GridBagConstraints gbc_lblMonthlyPayment = new GridBagConstraints();
        gbc_lblMonthlyPayment.fill = GridBagConstraints.HORIZONTAL;
        gbc_lblMonthlyPayment.insets = new Insets(0, 0, 5, 5);
        gbc_lblMonthlyPayment.gridx = 0;
        gbc_lblMonthlyPayment.gridy = 3;
        mainPanel.add(lblMonthlyPayment, gbc_lblMonthlyPayment);

        txtMonthlyPament = new JTextField();
        GridBagConstraints gbc_txtMonthlyPament = new GridBagConstraints();
        gbc_txtMonthlyPament.gridwidth = 2;
        gbc_txtMonthlyPament.insets = new Insets(0, 0, 5, 0);
        gbc_txtMonthlyPament.anchor = GridBagConstraints.NORTH;
        gbc_txtMonthlyPament.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtMonthlyPament.gridx = 1;
        gbc_txtMonthlyPament.gridy = 3;
        mainPanel.add(txtMonthlyPament, gbc_txtMonthlyPament);
        txtMonthlyPament.setColumns(10);

        JButton btnCalculate = new JButton("Calculate");
        btnCalculate.addActionListener(new ActionListener() 
            public void actionPerformed(ActionEvent e) 
                calculate();
            

            private void calculate() 
                //do the math here
                txtResult.setText("Calculate pressed!");
            
        );

        JLabel lblResult = new JLabel("Result:");
        GridBagConstraints gbc_lblResult = new GridBagConstraints();
        gbc_lblResult.fill = GridBagConstraints.HORIZONTAL;
        gbc_lblResult.insets = new Insets(0, 0, 0, 5);
        gbc_lblResult.gridx = 0;
        gbc_lblResult.gridy = 4;
        mainPanel.add(lblResult, gbc_lblResult);

        txtResult = new JTextField();
        GridBagConstraints gbc_txtResult = new GridBagConstraints();
        gbc_txtResult.insets = new Insets(0, 0, 0, 5);
        gbc_txtResult.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtResult.gridx = 1;
        gbc_txtResult.gridy = 4;
        mainPanel.add(txtResult, gbc_txtResult);
        txtResult.setColumns(10);
        GridBagConstraints gbc_btnCalculate = new GridBagConstraints();
        gbc_btnCalculate.gridx = 2;
        gbc_btnCalculate.gridy = 4;
        mainPanel.add(btnCalculate, gbc_btnCalculate);
    

    private static final long serialVersionUID = 1L;
    private JTextField txtLoanAmount;
    private JTextField txtLoanInterest;
    private JTextField txtLoanPeriod;
    private JTextField txtMonthlyPament;
    private JTextField txtResult;

    public static void main(String[] args) 
        SwingUtilities.invokeLater(new Runnable() 

            public void run() 
                GridExample g = new GridExample();

                 String text = "<html><h1 align='center'>Loan Program 1.0</h1>";
                    text = text + "This program lets you calculate the various aspects of loans <br />";
                    text = text + "If you are leaving a field empty then use 0 for its place <br />";
                    text = text + "<h1 align='center'>Text Fields To Enter</h1>";
                    text = text + "Monthly Payment: Enter values for: Loan Period, Loan Amount, and Loan Interest. Enter 0 for Monthly Payment. <br />";
                    text = text + "Loan Period: Enter Values for: Loan Amount, Loan Interest, and Monthly Payment. Enter 0 for Loan Period. <br />";

                g.setVisible(true);
                JOptionPane.showMessageDialog(g, new JLabel(text));
            
        );
    


【讨论】:

以上是关于JLabel 文本在窄列中而不是展开的主要内容,如果未能解决你的问题,请参考以下文章

将 JLabel 中的文本右对齐

如何更新JLabel文本?

如何使 JLabel 中的文本居中?

JLabel 或 JTable 单元格上的 ActionListener

组布局中的 JLabel - 冻结大小

使 JLabel 文本与中心垂直对齐