繁体   English   中英

GUI问题中图形上方的Java按钮

[英]Java buttons on top of graphics in a GUI issue

对于我的年终项目,我正在尝试制作一款游戏,该游戏可以帮助人们研究不同的问题,这些问题在GUI中显示。 理想情况下,用户可以使用按钮来查看其答案是否正确。 我使用变量ArrayList <String[]>变量作为GUI的基础,该变量将保存问题及其答案,并尝试制作按钮。

但是,当我尝试运行该程序时,按钮(在显示的代码中我只有一个)被切断了,因此我无法将它们放置在适当位置。 请帮忙!

有人请告诉我一个实际上已经过测试并且有效的解决方案! 我似乎无法根据到目前为止为我发布的内容来获取它!

在此处输入图片说明

这是我运行它时的样子:

这是程序的所有代码:

import java.awt.*;
import javax.swing.*;
import java.awt.geom.Line2D;
import java.util.*;
import java.awt.event.*;

public class EuroGUI extends JPanel {
    //Instantiate necessary variables.
    ArrayList <String[]> questions = new ArrayList <String[]>();  //Stores (Question + Answers, Correct Answer)

    int width = 1280;   //GUI Size
    int height = 720;   // ^
    int correct = 0;    //Number of correct answers
    int attempted = 0;  //Number of questions attempted
    int streak = 0;     //Number of correct answers in a row
    int points = 0;     //Points accumulated
    Font title = new Font("Serif", Font.PLAIN, 60);
    Font statsTitle = new Font("Serif", Font.PLAIN, 45);
    Font sig = new Font("Mistral", Font.PLAIN, 45);

    //Drop down options stuff
    JMenu ddMenu = new JMenu("Select an option");
    String[] dropDown = new String[] {"A", "B", "C", "D", "E"};

    String completion = "starting"; //Determines if the first time repainting

    Scanner keyboard = new Scanner(System.in);  //Make a keyboard object to test stuff

    public static void main(String[]args){  //Main Runner
        EuroGUI g = new EuroGUI();
        g.setUpScreen();
        g.repaint();
    }

    public void setUpScreen() {  //Create the physical GUI, which paints all graphics
                                 //Used http://www.mathcs.emory.edu/~cheung/Courses/377/Syllabus/8-JDBC/GUI/Progs/Layout1.java for buttons

        //Create actual GUI window and graphics.
        //Create actual GUI window and graphics.
    JFrame f = new JFrame("AP European History Study Tool");

    JPanel panelGrid = new JPanel();
    panelGrid.setLayout(new GridLayout());
    setLayout(null);

    JPanel panelBorder = new JPanel();
    panelBorder.setLayout(new BorderLayout());
    JButton xA = new JButton("Choice A");
    panelGrid.add(xA, "West");

    panelBorder.setLocation(500,500);
    f.getContentPane().add(panelBorder);
    f.setResizable(false);
    f.setVisible(true);
    f.setSize(width, height);
    f.setBackground(Color.lightGray);
    f.add(this);

    }
    public void paintComponent(Graphics g) {  //Draws information on the GUI  (Found information on graphics 2D at http://www.tutorialspoint.com/javaexamples/gui_line.htm)
        Graphics2D g2 = (Graphics2D) (g);

        //Draw a background box which will cover anything that was not re-painted over.
        g.setColor(Color.lightGray);
        g.fillRect (0, 1280, 0, 720);

        //Title "interface"
            //Change color back for the lines;
            g.setColor(Color.blue);
            //Enable bolder lines.
            g2.setStroke(new BasicStroke(6));

            //Create a box of lines around the title.
            g2.draw(new Line2D.Double(200, 0, 200, 120));
            g2.draw(new Line2D.Double(200, 120, 1070, 120));
            g2.draw(new Line2D.Double(1070, 0, 1070, 120));
            g2.draw(new Line2D.Double(200, 0, 1070, 0));

            //Fill in box with title with some colors :)
            g.setColor(Color.green);
            g.fillRect (200, 0, 870, 120);

            //Write title
            g2.setFont(title);
            g.setColor(Color.cyan);
            g.drawString("AP European History Study Tool", 240, 80);
            g.setColor(Color.black);
            g.drawString("AP European History Study Tool", 238, 78);

        //Signiature on Title
            g.setColor(Color.white);
            g2.setFont(sig);
            g.drawString("by My Name", 600, 120);
            g.setColor(Color.blue);
            g.drawString("by My Name", 598, 118);

        //Statistics Bar Outline
            g.setColor(Color.blue);
            g2.draw(new Line2D.Double(1000, 170, 1000, 670));
            g2.draw(new Line2D.Double(1000, 170, 1280, 170));
            g2.draw(new Line2D.Double(1280, 170, 1280, 670));
            g2.draw(new Line2D.Double(1000, 670, 1280, 670));
            g2.setStroke(new BasicStroke(6));
            g.setColor(Color.black);
            g.fillRect (1000, 170, 1280, 500);
            g.setColor(Color.green); //Underline
            g2.setStroke(new BasicStroke(2));
            g2.draw(new Line2D.Double(1055, 230, 1215, 230));
            g2.setStroke(new BasicStroke(6));

        //Overall Score
            g2.setFont(statsTitle);
            g2.setColor(Color.green);
            g.drawString("Statistics", 1055, 220);
            g2.setColor(Color.cyan);
            g.drawString(correct + "/" + attempted + " Correct", 1035, 285); 

        //Streak
            if (streak >= 3)
            {
                g2.setColor(Color.red);
                g.drawString(streak + " Streak", 1060, 340);
            }
            else{
                g2.setColor(Color.cyan);
                g.drawString(streak + " Streak", 1060, 340);
            }


        if (completion.equals("starting")){

        }
    }
}

这是断开油漆链的症状。

Graphics是共享资源,也就是说,使用同一Graphics上下文来绘制绘制周期内的所有组件。

paintComponent的工作之一是通过在绘制任何内容之前清除它来准备Graphics上下文以进行绘制。

所以代替...

public void paintComponent(Graphics g) {  //Draws information on the GUI  (Found information on graphics 2D at http://www.tutorialspoint.com/javaexamples/gui_line.htm)
    Graphics2D g2 = (Graphics2D) (g);

尝试使用

public void paintComponent(Graphics g) {  //Draws information on the GUI  (Found information on graphics 2D at http://www.tutorialspoint.com/javaexamples/gui_line.htm)
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) (g);

像素完美的布局是现代UI中的一种幻觉。 您无法控制诸如字体规格,dpi或渲染管道之类的因素,这些因素都会影响单个组件可能需要的空间量。 相反,您应该使用适当的布局管理器,并考虑使用复合布局来生成更复杂的解决方案

更新了示例

有很多错误,主要问题是, panelGrid没有添加到任何东西中。 null布局管理器也无济于事。

您还将所有精力集中在一个面板上,这将使生活变得混乱。

相反,尝试将每个部分分成其自己的组件并专注于各个需求,从长远来看,您会发现它更容易管理。

在此处输入图片说明

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;

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

    public Example() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new HeaderPane(), BorderLayout.NORTH);
                frame.add(new StatisticsPane(), BorderLayout.EAST);
                frame.add(new QuestionPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class HeaderPane extends JPanel {

        public HeaderPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 1;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.SOUTH;
//            gbc.ipadx = 100;
            NamePane namePane = new NamePane();
            FontMetrics fm = namePane.getFontMetrics(namePane.getFont());
            add(namePane, gbc);

            gbc.insets = new Insets(0, 0, fm.getDescent(), 0);

            gbc.gridx = 0;
            gbc.gridwidth = 2;
            gbc.ipadx = 10;
            gbc.ipady = 10;
            gbc.anchor = GridBagConstraints.CENTER;
            add(new TitlePane(), gbc);
        }

        public class ShadowLabel extends JPanel {

            private String text;
            private Color shadowColor;
            private int shadowOffset;

            public ShadowLabel(String text, Color shadowColor) {
                this.text = text;
                this.shadowColor = shadowColor;
                this.shadowOffset = 2;
            }



            public int getShadowOffset() {
                return shadowOffset;
            }

            public void setShadowOffset(int shadowOffset) {
                this.shadowOffset = shadowOffset;
            }

            @Override
            public Dimension getPreferredSize() {
                FontMetrics fm = getFontMetrics(getFont());
                return new Dimension(fm.stringWidth(getText()), fm.getHeight());
            }

            public String getText() {
                return text;
            }

            public Color getShadowColor() {
                return shadowColor;
            }

            public void setText(String text) {
                this.text = text;
                repaint();
            }

            public void setShadowColor(Color shadowColor) {
                this.shadowColor = shadowColor;
                repaint();
            }

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setFont(getFont());
                FontMetrics fm = g.getFontMetrics();
                int x = (getWidth() - fm.stringWidth(getText())) / 2;
                int y = (getHeight() - fm.getHeight()) / 2;
                g.setColor(getShadowColor());
                g.drawString(getText(), x + getShadowOffset(), y + getShadowOffset() + fm.getAscent());
                g.setColor(getForeground());
                g.drawString(getText(), x, y + fm.getAscent());
            }


        }

        public class TitlePane extends ShadowLabel {

            public TitlePane() {
                super("AP European History Study Tool", Color.CYAN);
                setBackground(Color.GREEN);
                setBorder(new MatteBorder(0, 1, 1, 1, Color.BLUE));
                setFont(new Font("Serif", Font.PLAIN, 60));
            }

        }

        public class NamePane extends ShadowLabel {

            public NamePane() {
                super("by Me", Color.WHITE);
                setForeground(Color.BLUE);
                setFont(new Font("Mistral", Font.PLAIN, 45));
                setOpaque(false);
            }

        }

    }

    public class StatisticsPane extends JPanel {

        private JLabel score;
        private JLabel streak;

        public StatisticsPane() {
            setLayout(new BorderLayout());
            setBackground(Color.BLACK);
            setBorder(new CompoundBorder(new LineBorder(Color.BLUE), new EmptyBorder(4, 4, 4, 4)));

            JLabel statistics = new JLabel("Statistics");
            statistics.setFont(new Font("Serif", Font.PLAIN, 45));
            statistics.setForeground(Color.GREEN);
            statistics.setBorder(new CompoundBorder(new MatteBorder(0, 0, 1, 0, Color.GREEN), new EmptyBorder(4, 4, 4, 4)));
            add(statistics, BorderLayout.NORTH);

            score = new JLabel("0/0 correct");
            score.setForeground(Color.GREEN);
            score.setFont(new Font("Serif", Font.PLAIN, 45));
            streak = new JLabel("0 streak");
            streak.setForeground(Color.GREEN);
            streak.setFont(new Font("Serif", Font.PLAIN, 45));

            JPanel pnl = new JPanel(new GridBagLayout());
            pnl.setOpaque(false);
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            pnl.add(score, gbc);
            gbc.gridy++;
            gbc.weighty = 1;
            gbc.anchor = GridBagConstraints.NORTH;
            pnl.add(streak, gbc);

            add(pnl);

        }

    }

    public class QuestionPane extends JPanel {

        public QuestionPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.anchor = GridBagConstraints.WEST;
            JButton xA = new JButton("Choice A");
            add(xA, gbc);
        }

    }
}

我还将数据和UI的管理分开,以便通过某种可以响应UI更改的模型来管理数据,反之亦然。 这意味着您的UI成为数据模型的可视化表示形式,并允许两者解耦并彼此独立地工作...

看一下模型-视图-控制器以了解更多详细信息。 注意:Swing使用了此版本,但更像是Model-View和Controller

您还应该看看使用JFC / Swing创建GUI来了解如何更好地利用Swing中可用的现成组件。

您没有正确设置布局。 可能不完全是您要查找的内容,但是如果您从FlowLayout更改为BorderLayout,它似乎可以解决您的问题。 另外,您不会在代码中的任何地方使用panel2,因此可以将其删除。

public void setUpScreen() {  //Create the physical GUI, which paints all graphics
                             //Used http://www.mathcs.emory.edu/~cheung/Courses/377/Syllabus/8-JDBC/GUI/Progs/Layout1.java for buttons

    //Create actual GUI window and graphics.
    JFrame f = new JFrame("AP European History Study Tool");

    JPanel panelGrid = new JPanel();
    panelGrid.setLayout(new GridLayout());
    setLayout(null);

    JPanel panelBorder = new JPanel();
    panelBorder.setLayout(new BorderLayout());
    JButton xA = new JButton("Choice A");
    panelGrid.add(xA, "West");

    panelBorder.setLocation(500,500);
    f.getContentPane().add(panelBorder);
    f.setResizable(false);
    f.setVisible(true);
    f.setSize(width, height);
    f.setBackground(Color.lightGray);
    f.add(this);


}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM