JLabel,流布局。使 JLabel 居中?

Posted

技术标签:

【中文标题】JLabel,流布局。使 JLabel 居中?【英文标题】:JLabel, FlowLayout. Centering the JLabel? 【发布时间】:2014-08-03 06:36:50 【问题描述】:

所以我正在创建这个“彩票”,我尝试了一些不同的方法来将我的 JLabel 的文本居中,但它只是从屏幕中间的右侧开始。这是我的代码和我的意思的图片。

这是我第一次在此表单上发帖,如果我遗漏了什么,请随时纠正我。

代码:

import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.HeadlessException;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
/**
 * Author Samy
 */
public class Game extends JFrame 
    public Game() throws HeadlessException

        int width = 720;
        int height = width/16*9;

        setSize(width,height);
        setTitle("The Lottery - V1.0");
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        setLayout(new FlowLayout());

        String winnings;
        double lotteryChance = Math.random()*100;

        if (lotteryChance > 50) 
            winnings = ("You've won $100!");
         else if (lotteryChance < 50 && lotteryChance > 20) 
            winnings = ("You've won $500!");
         else if (lotteryChance < 20 && lotteryChance > 5) 
            winnings = ("You've won $2,000!");
         else if (lotteryChance < 5 && lotteryChance > 1) 
            winnings = ("You've won $5,000!");
         else if (lotteryChance < 1 && lotteryChance > 0.1) 
            winnings = ("You've won $25,000!");
         else if (lotteryChance < 0.1 && lotteryChance > 0.01) 
            winnings = ("You've won $50,000!");
         else if (lotteryChance < 0.01 && lotteryChance > 0.001) 
            winnings = ("You've won $250,000!");
         else if (lotteryChance < 0.001 && lotteryChance > 0) 
            winnings = ("YOU'VE WON THE JACKPOT! $1,000,000!!!");
         else winnings = ("Something went wrong, no winnings this round.");

        int number = 74;
        JLabel label = new JLabel("<html>The Lottery<BR>Authored by: Samy<BR><BR>-=Prize Board=-<BR><BR>100  - 50:     $100<BR>50   - 20:     $500<BR>20   - 5:      $2,000<BR>5    - 1:      $5,000<BR>1    - 0.1:    $25,000<BR>0.1  - 0.01:   $50,000<BR>0.01 - 0.001:  $250,000<BR>0.001 - 0.0001: $1,000,000<BR><BR>Your number is: "+lotteryChance+"<BR><BR>"+winnings+"</HTML>");


        getContentPane().add(label);


    
    public static void main(String args[])
        new Game().setVisible(true);
    

【问题讨论】:

奖牌应该放在JTable中,以便于阅读。您的奖金范围不应重叠,例如 50。 你建议怎么做? 【参考方案1】:

这是我使用 Swing 组件的彩票游戏版本,以展示 Java Swing 应用程序的外观。

我将所有 Java 类放在一起,以便于复制和粘贴。这些类应该在单独的文件中。

这是我对代码所做的更改。

    在 main 方法中,我将启动代码放在 SwingUtilities 的 invokeLater 方法调用中。我这样做是为了将 Swing 组件定义和执行放在 Event Dispatch thread 上。

    在 Game 类中,我使用了 JFrame,而不是扩展 JFrame。唯一应该扩展 Swing 组件的时候是在重写其中一个组件方法时。

    我创建了两个 JPanel 来放入 JFrame。顶部 JPanel WinningsPanel 包含彩票奖金表。为此,我使用了一个 JTable 来分隔这些值。底部的 JPanel,ButtonPanel,包含一个 JButton,让应用程序生成一个数字并显示彩票奖金。

    我创建了两个模型类。第一个模型类 LotteryLine 保存彩票表中一行的值。第二个模型类 GameModel 保存整个彩票表并生成随机数。

    我为 JTable 创建了一个彩票表模型。这让我可以控制彩票表中数值的显示。

    ButtonPanel 包含一个控制器 PickNumberActionListener,它生成一个随机的彩票号码并显示号码和奖金。

代码如下:

package com.ggl.testing;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
/**
 * Author Samy
 */
public class Game 

    private GameModel model;

    private JFrame frame;

    public Game() throws HeadlessException 

        model = new GameModel();

        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("The Lottery - Version 1.0");
        frame.setLocationByPlatform(true);
        frame.setLayout(new BorderLayout());

        WinningsPanel wPanel = new WinningsPanel(model);
        frame.add(wPanel.getPanel(), BorderLayout.NORTH);

        ButtonPanel bPanel = new ButtonPanel(model);
        frame.add(bPanel.getPanel(), BorderLayout.SOUTH);

        frame.pack();
    

    public JFrame getFrame() 
        return frame;
    

    public static void main(String args[])
        SwingUtilities.invokeLater(new Runnable() 
            @Override
            public void run() 
                new Game().getFrame().setVisible(true);
            
        );
    

    public class LotteryLine 

        private double lowValue;
        private double highValue;

        private int prize;

        private NumberFormat nf = NumberFormat.getCurrencyInstance();

        public LotteryLine(double highValue, double lowValue, 
                int prize) 
            this.highValue = highValue;
            this.lowValue = lowValue;
            this.prize = prize;
        

        public double getLowValue() 
            return lowValue;
        

        public double getHighValue() 
            return highValue;
        

        public int getPrize() 
            return prize;
        

        public String getFormattedPrize() 
            return nf.format(prize);
        

        public String getLeftPaddedPrize() 
            StringBuilder builder = new StringBuilder();
            String s = getFormattedPrize();

            for (int i = s.length(); i < 16; i++) 
                builder.append(' ');
            
            builder.append(s);

            return builder.toString();
        

    

    public class GameModel 

        private double randomNumber;

        private List<LotteryLine> lotteryList;

        public GameModel() 
            this.lotteryList = new ArrayList<LotteryLine>();
            createLotteryList();
        

        private void createLotteryList() 
            lotteryList.add(new LotteryLine(100D, 50D, 100));
            lotteryList.add(new LotteryLine(50D, 20D, 500));
            lotteryList.add(new LotteryLine(20D, 5D, 2000));
            lotteryList.add(new LotteryLine(5D, 1D, 5000));
            lotteryList.add(new LotteryLine(1D, 0.1D, 25000));
            lotteryList.add(new LotteryLine(0.1D, 0.01D, 50000));
            lotteryList.add(new LotteryLine(0.01D, 0.001D, 250000));
            lotteryList.add(new LotteryLine(0.001D, 0.0001D, 1000000));
        

        public double generateRandomNumber() 
            this.randomNumber = Math.random() * 100D;
            return randomNumber;
        

        public List<LotteryLine> getLotteryList() 
            return lotteryList;
        

        public LotteryLine getLotteryLine(double randomNumber) 
            for (LotteryLine lotteryLine : lotteryList) 
                if (randomNumber > lotteryLine.getLowValue()) 
                    return lotteryLine;
                
            
            throw new IllegalArgumentException();
        
    

    public class WinningsPanel 

        private GameModel model;

        private JPanel panel;

        public WinningsPanel(GameModel model) 
            this.model = model;
            createPartControl();
        

        private void createPartControl() 
            panel = new JPanel();
            panel.setLayout(new BorderLayout());

            JPanel labelPanel = new JPanel();
            labelPanel.setLayout(new BoxLayout(
                    labelPanel, BoxLayout.PAGE_AXIS));

            JLabel writtenLabel = new JLabel("Written by: Samy");
            writtenLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
            labelPanel.add(writtenLabel);

            labelPanel.add(Box.createVerticalStrut(20));

            JLabel prizeLabel = new JLabel("Prize Table");
            prizeLabel.setFont(new Font("default", Font.BOLD, 32));
            prizeLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
            labelPanel.add(prizeLabel);

            panel.add(labelPanel, BorderLayout.NORTH);

            LotteryTableModel tableModel = new LotteryTableModel(model);

            JTable lotteryTable = new JTable(tableModel);
            int height = tableModel.getRowCount() * 
                    lotteryTable.getRowHeight();
            lotteryTable.setPreferredScrollableViewportSize(
                    new Dimension(300, height));
            JScrollPane scrollPane = new JScrollPane(lotteryTable);
            panel.add(scrollPane, BorderLayout.CENTER);
        

        public JPanel getPanel() 
            return panel;
        

    

    public class LotteryTableModel extends AbstractTableModel 

        private static final long   serialVersionUID    = 
                7330112393676204265L;

        private GameModel model;

        private String[] columns = "High Value", "Low Value", "Prize";

        public LotteryTableModel(GameModel model) 
            this.model = model;
        

        @Override
        public int getRowCount() 
            return model.getLotteryList().size();
        

        @Override
        public int getColumnCount() 
            return columns.length;
        

        @Override
        public String getColumnName(int columnIndex) 
            return columns[columnIndex];
        

        @Override
        public Class<?> getColumnClass(int column) 
            switch (column) 
                case 0:
                case 1:
                    return Double.class;
                case 2:
                    return String.class;
                default:
                    return String.class;
            
        

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) 
            LotteryLine lotteryLine = 
                    model.getLotteryList().get(rowIndex);
            switch (columnIndex) 
            case 0: return lotteryLine.getHighValue();
            case 1: return lotteryLine.getLowValue();
            case 2: return lotteryLine.getLeftPaddedPrize();
            default: return "";
            
        

    

    public class ButtonPanel 

        private GameModel model;

        private JLabel numberLabel;
        private JLabel prizeLabel;

        private JPanel panel;

        public ButtonPanel(GameModel model) 
            this.model = model;
            createPartControl();
        

        private void createPartControl() 
            panel = new JPanel();
            panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));

            panel.add(Box.createVerticalStrut(10));

            JButton playButton = new JButton("Pick Number");
            playButton.addActionListener(new PickNumberActionListener());
            playButton.setAlignmentX(JButton.CENTER_ALIGNMENT);
            panel.add(playButton);

            panel.add(Box.createVerticalStrut(20));

            numberLabel = new JLabel(" ");
            numberLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
            panel.add(numberLabel);

            prizeLabel = new JLabel(" ");
            prizeLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
            panel.add(prizeLabel);
        

        public void updateNumberLabel(double number) 
            StringBuilder builder = new StringBuilder();
            builder.append("Your number is ");
            builder.append(String.format("%.4f", number));
            numberLabel.setText(builder.toString());
        

        public void updatePrizeLabel(String prize) 
            StringBuilder builder = new StringBuilder();
            builder.append("You've won ");
            builder.append(prize);
            prizeLabel.setText(builder.toString());
        

        public JPanel getPanel() 
            return panel;
        

        public class PickNumberActionListener implements ActionListener 

            @Override
            public void actionPerformed(ActionEvent e) 
                double number = model.generateRandomNumber();
                LotteryLine lotteryLine = model.getLotteryLine(number);
                updateNumberLabel(number);
                updatePrizeLabel(lotteryLine.getFormattedPrize());
            

        

    

【讨论】:

这看起来很不错,但我在这些方面还不够好,无法理解你所做的一半,但它看起来确实很棒。 @Samy:如果你不接触它,你是不会明白的。将我的代码保存在某个地方并偶尔回来查看它。您最终会掌握其中的大部分内容。【参考方案2】:

FlowLayout.CENTER 传递给alignment 参数的FlowLayout 构造函数。

Here's the constructor doc

例子:

setLayout(new FlowLayout(FlowLayout.CENTER));

编辑:

尝试将&lt;center&gt; HTML 标记添加到标签的 HTML 格式中。这应该使标签中的所有文本居中。

【讨论】:

我试过了,但没有任何改变?你的意思是我应该改变这一行: setLayout(new FlowLayout()); to: setLayout(new FlowLayout(FlowLayout.CENTER)); 对,我自己也试过了,好像没太大变化。尝试在标签文本中添加center 标签。 HTML 部分的中心标签?编辑:这有效!谢啦! :D

以上是关于JLabel,流布局。使 JLabel 居中?的主要内容,如果未能解决你的问题,请参考以下文章

通过设置最大宽度使 JLabel 包装它的文本

JAVA怎样使Label中的文字居中对齐!

在使用形状(多边形)设置 JLabel 的 Clip 之前,getClip() 仍然返回 null

Java JLabel中HTML表格单元格中的文本垂直居中

使 JLabel 文本与中心垂直对齐

JLabel 中心内容分 3 行