我如何编写代码来显示每个 JPanel 中的每个字母,以及如何旋转。 (JFrame、NetBeans)

Posted

技术标签:

【中文标题】我如何编写代码来显示每个 JPanel 中的每个字母,以及如何旋转。 (JFrame、NetBeans)【英文标题】:How do i write a code to display every letter in every JPanel, and how do I rotate. (JFrame, NetBeans) 【发布时间】:2020-10-10 06:25:53 【问题描述】:

我是 Java 新手,我在课堂上被分配为以下问题开发代码,我只能做设计,之后我不知道如何继续为每个问题添加操作按钮。

这是问题:

https://www.chegg.com/homework-help/questions-and-answers/write-java-application-creates-frame-similar-one-shown--four-letter-word-shown-four-panels-q52352988

如果有人解决过,请分享。 提前感谢您的帮助!

【问题讨论】:

我很困惑。 JFrame 上唯一的按钮是“旋转”按钮。 【参考方案1】:

由于这是家庭作业,我不会提供完整的代码。我会提供sn-ps。

这是我创建的 GUI。我希望我可以将其显示为动画 GIF。

我添加了一个停止按钮来停止单词旋转。

我通过将问题分解为越来越小的步骤来编写代码,然后对每个步骤进行编码。在完成之前,我对 GUI 进行了许多测试。有些测试失败了,我不得不修改代码。

我写了 6 节课。主类创建了JFrame,字母面板组,底部控制面板。我写了一个LetterPanel 类来创建一个字母面板。我写了 3 个actionListener 类,一个用于JComboBox,一个用于旋转按钮,一个用于停止按钮。我写了一个 Animation 类,它每秒旋转字母。

这是我用来获得 4 种绿色的颜色。

    Color[] colors =  new Color(50, 117, 1),
            new Color(65, 159, 0), new Color(88, 201, 5),
            new Color(107, 242, 2)
    ;

设置主要的JPanel 来保存4 个LetterPanel 对象有点棘手。以下是我的做法。

    JPanel panel = new JPanel();
    panel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));

LetterPanel 类扩展了 JPanel 并覆盖了 paintComponent 方法。首先,我调用了super.paintComponent 方法。始终首先调用super.paintComponent 方法。然后,我画了背景颜色。然后,我画了这封信。

为了在每个LetterPanel 中绘制字母,我使用了以下代码。

    /**
     * Draw a String centered in the middle of the panel.
     *
     * @param g2d The Graphics2D instance.
     * @param text The String to draw.
     * @param font The Font to draw with.
     */
    public void drawCenteredString(Graphics2D g2d,
            String text, Font font) 
        FontMetrics metrics = g2d.getFontMetrics(font);
        int x = (getWidth() - metrics.stringWidth(text)) / 2;
        int y = ((getHeight() - metrics.getHeight()) / 2) +
                metrics.getAscent();
        g2d.setFont(font);
        g2d.drawString(text, x, y);
    

JComboBox actionListener 从 JComboBox 中获取选定的单词。 Oracle 教程How to Use Combo Boxes 告诉您我是如何设置单词 JComboBox。

旋转按钮actionListener 检查是否同时检查了JCheckBox 字段。然后它检查是否没有检查JCheckBox 字段。最后,它启动了一个Animation 线程。

停止按钮停止Animation 线程。

Animation 线程旋转单词并暂停 1 秒以让您看到旋转。

这是运行循环。

    @Override
    public void run() 
        while (running) 
            updatePanel();
            sleep(1000L);
            if (leftSelected) 
                word = rotateLeft(word);
             else 
                word = rotateRight(word);
            
        
    

这是我的轮换方法。

    private String rotateLeft(String word) 
        return word.substring(1) + word.substring(0, 1);
    

    private String rotateRight(String word) 
        return word.substring(word.length() - 1) +
                word.substring(0, word.length() - 1);
    

编辑添加;

我忘了我已经回答了这个问题。时间已经过去了,所以我将发布整个应用程序。我将附加类设为内部类,因此我可以将此代码作为一个块发布。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class RotateWord implements Runnable 

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

    private Animation animation;

    private JCheckBox leftBox;
    private JCheckBox rightBox;

    private JComboBox<String> wordComboBox;

    private JFrame frame;

    private LetterPanel[] letterPanel;

    private String word;

    public RotateWord() 
        this.word = "WORD";
    

    @Override
    public void run() 
        frame = new JFrame("Rotate Word");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createWordPanel(word), BorderLayout.CENTER);
        frame.add(createControlPanel(word),
                BorderLayout.AFTER_LAST_LINE);

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

    private JPanel createWordPanel(String word) 
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));

        Color[] colors =  new Color(50, 117, 1),
                new Color(65, 159, 0), new Color(88, 201, 5),
                new Color(107, 242, 2)
        ;

        letterPanel = new LetterPanel[word.length()];
        for (int i = 0; i < word.length(); i++) 
            letterPanel[i] = new LetterPanel(colors[i],
                    word.charAt(i));
            panel.add(letterPanel[i]);
        

        return panel;
    

    public void updateWordPanel(String word) 
        for (int i = 0; i < word.length(); i++) 
            letterPanel[i].setLetter(word.charAt(i));
            letterPanel[i].repaint();
        
    

    private JPanel createControlPanel(String word) 
        JPanel panel = new JPanel();

        String[] words =  "ABLE", "BATH", "EXIT", "WORD" ;
        wordComboBox = new JComboBox<>(words);
        wordComboBox.setSelectedItem(word);
        wordComboBox.addActionListener(new WordListener());
        panel.add(wordComboBox);

        leftBox = new JCheckBox("Left");
        panel.add(leftBox);

        rightBox = new JCheckBox("Right");
        panel.add(rightBox);

        JButton rotateButton = new JButton("Rotate");
        rotateButton.addActionListener(new RotateListener());
        panel.add(rotateButton);

        JButton stopButton = new JButton("Stop");
        stopButton.addActionListener(new StopListener());
        panel.add(stopButton);

        return panel;
    

    public class LetterPanel extends JPanel 

        private static final long serialVersionUID = 1L;

        private char letter;

        private Color backgroundColor;

        private Font font;

        public LetterPanel(Color backgroundColor, char letter) 
            this.backgroundColor = backgroundColor;
            this.letter = letter;
            this.font = getFont().deriveFont(96f)
                    .deriveFont(Font.BOLD);
            this.setPreferredSize(new Dimension(120, 200));
        

        public void setLetter(char letter) 
            this.letter = letter;
        

        @Override
        protected void paintComponent(Graphics g) 
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(backgroundColor);
            g2d.fillRect(0, 0, getWidth(), getHeight());

            g2d.setColor(Color.BLACK);
            drawCenteredString(g2d, Character.toString(letter),
                    font);
        

        /**
         * Draw a String centered in the middle of the panel.
         *
         * @param g2d The Graphics2D instance.
         * @param text The String to draw.
         * @param font The Font to draw with.
         */
        public void drawCenteredString(Graphics2D g2d,
                String text, Font font) 
            FontMetrics metrics = g2d.getFontMetrics(font);
            int x = (getWidth() - metrics.stringWidth(text)) / 2;
            int y = ((getHeight() - metrics.getHeight()) / 2) +
                    metrics.getAscent();
            g2d.setFont(font);
            g2d.drawString(text, x, y);
        

    

    public class WordListener implements ActionListener 

        @Override
        public void actionPerformed(ActionEvent event) 
            word = (String) wordComboBox.getSelectedItem();
            updateWordPanel(word);
        

    

    public class RotateListener implements ActionListener 

        @Override
        public void actionPerformed(ActionEvent event) 
            boolean leftSelected = leftBox.isSelected();
            boolean rightSelected = rightBox.isSelected();

            if (leftSelected && rightSelected) 
                word = "OOPS";
                updateWordPanel(word);
                return;
            

            if (!leftSelected && !rightSelected) 
                return;
            

            word = (String) wordComboBox.getSelectedItem();
            updateWordPanel(word);

            animation = new Animation(leftSelected);
            new Thread(animation).start();
        

    

    public class StopListener implements ActionListener 

        @Override
        public void actionPerformed(ActionEvent event) 
            if (animation != null) 
                animation.setRunning(false);
                animation = null;
            
        

    

    public class Animation implements Runnable 

        private boolean leftSelected;

        private volatile boolean running;

        public Animation(boolean leftSelected) 
            this.leftSelected = leftSelected;
            this.running = true;
        

        @Override
        public void run() 
            while (running) 
                updatePanel();
                sleep(1000L);
                if (leftSelected) 
                    word = rotateLeft(word);
                 else 
                    word = rotateRight(word);
                
            
        

        public synchronized void setRunning(boolean running) 
            this.running = running;
        

        private String rotateLeft(String word) 
            return word.substring(1) + word.substring(0, 1);
        

        private String rotateRight(String word) 
            return word.substring(word.length() - 1) +
                    word.substring(0, word.length() - 1);
        

        private void updatePanel() 
            SwingUtilities.invokeLater(new Runnable() 
                @Override
                public void run() 
                    updateWordPanel(word);
                
            );
        

        private void sleep(long duration) 
            try 
                Thread.sleep(duration);
             catch (InterruptedException e) 
                // Deliberately left blank

            
        

    


【讨论】:

以上是关于我如何编写代码来显示每个 JPanel 中的每个字母,以及如何旋转。 (JFrame、NetBeans)的主要内容,如果未能解决你的问题,请参考以下文章

如何将每个 JPanel 向左或向右对齐到主 JPanel

单击jPanel(Java)时如何调用函数?

Swing:如何在每个组件、JPanel、JButton 等上绘制动画?

如何突出显示主 JPanel 中的特定子面板?

如何从 Jpanel 中的 JTextField 获取值并将其发送到其他 JPanel?

如何通过单击 JButton 添加 JPanel?