带有 Graphics.draw 的 JComponents

我正在尝试使用 JPanel 制作一个简单的游戏。

我正在使用 Graphics Draw 来显示所有信息,包括文本,但我需要添加用户输入。

我正在考虑将 JTextField 与绝对定位一起使用以使其与正在绘制的内容一起工作,但我听说绝对定位不是设置 JPanel 的好方法。

有没有更好的方法在同一个面板中同时使用图形绘制和 JComponents?


HUX布斯
浏览 68回答 2
2回答

海绵宝宝撒

解决方案:使用布局管理器为什么不简单地让另一个 JPanel 持有绘图 JPanel,一个使用 BorderLayout 并保持在该BorderLayout.CENTER位置的 JPanel。然后,您可以将 JTextField 或其他控件组件放置在外部 JPanel 中的其他位置。您还可以将布局管理器添加到绘图 JPanel,然后使用布局将组件添加到此。请记住,如果您在绘图 JPanel 顶部添加任何 JPanel,则添加的 JPanel 应该是透明的,即myPanel.setOpaque(false)应该在它们上调用,以便下面的绘图显示出来。例如——运行这个程序来看看我的意思:import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.GradientPaint;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.GridLayout;import javax.swing.*;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;public class GradientPaintEg extends JPanel {    private DrawingPanel drawingPanel = new DrawingPanel();    private JSlider hue1Slider = new JSlider(0, 100, 0);    private JSlider hue2Slider = new JSlider(0, 100, 0);    public GradientPaintEg() {        Color color = drawingPanel.getColor1();        float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);        int value = (int) (hsb[0] * 100);        hue1Slider.setValue(value);        color = drawingPanel.getColor2();        hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);        value = (int) (hsb[0] * 100);        hue2Slider.setValue(value);        hue1Slider.setMajorTickSpacing(20);        hue1Slider.setMinorTickSpacing(5);        hue1Slider.setPaintTicks(true);        hue1Slider.setPaintLabels(true);        hue1Slider.setPaintTrack(true);        hue1Slider.addChangeListener(new SliderListener(hue1Slider, drawingPanel, true));        hue1Slider.setOpaque(false);        hue2Slider.setMajorTickSpacing(20);        hue2Slider.setMinorTickSpacing(5);        hue2Slider.setPaintTicks(true);        hue2Slider.setPaintLabels(true);        hue2Slider.setPaintTrack(true);        hue2Slider.addChangeListener(new SliderListener(hue2Slider, drawingPanel, false));        hue2Slider.setOpaque(false);        JPanel sliderPanel = new JPanel(new GridLayout(0, 1, 4, 4));        sliderPanel.add(hue1Slider);        sliderPanel.add(hue2Slider);        sliderPanel.setOpaque(false);        setLayout(new BorderLayout());        // if you want to add the slider panel to the main JPanel:        // add(sliderPanel, BorderLayout.PAGE_START);        add(drawingPanel);        // if you want to add the sliderPanel to the drawing JPanel        drawingPanel.setLayout(new BorderLayout());        drawingPanel.add(sliderPanel, BorderLayout.PAGE_START);    }    private class SliderListener implements ChangeListener {        private JSlider slider;        private DrawingPanel drawingPanel;        private boolean color1Listener;        public SliderListener(JSlider slider, DrawingPanel drawingPanel, boolean color1Listener) {            this.slider = slider;            this.drawingPanel = drawingPanel;            this.color1Listener = color1Listener;        }        @Override        public void stateChanged(ChangeEvent e) {            int value = slider.getValue();            float hue = value / 100f;            Color c = Color.getHSBColor(hue, 1f, 1f);            if (color1Listener) {                drawingPanel.setColor1(c);            } else {                drawingPanel.setColor2(c);            }        }    }    private static void createAndShowGui() {        GradientPaintEg mainPanel = new GradientPaintEg();        JFrame frame = new JFrame("GradientPaintEg");        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        frame.getContentPane().add(mainPanel);        frame.pack();        frame.setLocationRelativeTo(null);        frame.setVisible(true);    }    public static void main(String[] args) {        SwingUtilities.invokeLater(() -> createAndShowGui());    }}class DrawingPanel extends JPanel {    private static final int PREF_W = 600;    private static final int PREF_H = PREF_W;    private static final float X2 = 20;    private static final float Y2 = X2;    private Color color1 = Color.RED;    private Color color2 = Color.BLUE;    public Color getColor1() {        return color1;    }    public void setColor1(Color color1) {        this.color1 = color1;        repaint();    }    public Color getColor2() {        return color2;    }    public void setColor2(Color color2) {        this.color2 = color2;        repaint();    }    @Override    protected void paintComponent(Graphics g) {        super.paintComponent(g);        Graphics2D g2 = (Graphics2D) g;        g2.setPaint(new GradientPaint(0, 0, color1, X2, Y2, color2, true));        g2.fillRect(0, 0, getWidth(), getHeight());    }    @Override    public Dimension getPreferredSize() {        if (isPreferredSizeSet()) {            return super.getPreferredSize();        }        return new Dimension(PREF_W, PREF_H);    }}class DrawingPanel在这个代码示例中,我有一个 JPanel,它在另一个主 JPanel中绘制、调用和使用,GradientPaintEg该类:public class GradientPaintEg extends JPanel {    private DrawingPanel drawingPanel = new DrawingPanel();如果我想向绘图面板添加组件,我首先给它一个布局,然后添加组件。例如,有一个 JPanel 保存了调用的 JSlider sliderPanel,我使用 BorderLayout 添加到 DrawingPanel 实例:drawingPanel.setLayout(new BorderLayout());drawingPanel.add(sliderPanel, BorderLayout.PAGE_START);这会将滑块面板添加到绘图面板的顶部。但还要注意,我必须先使 sliderPanel 不透明:JPanel sliderPanel = new JPanel(new GridLayout(0, 1, 4, 4));sliderPanel.add(hue1Slider);sliderPanel.add(hue2Slider);sliderPanel.setOpaque(false);我还使 JSlider 本身不透明,以便底层绘图显示:// ......hue1Slider.setOpaque(false);// ......hue2Slider.setOpaque(false);

心有法竹

JTextfield这是使用布局管理器在面板上组合用户输入和绘画的基本 mcve :import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JTextField;import javax.swing.SwingUtilities;import javax.swing.WindowConstants;class DrawingPanel extends JPanel {    private final JButton update;    private final JTextField input;    private final static int W = 300, H = 350, RADIUS = 100, GAP = 50;    private String text;    public DrawingPanel() {        setPreferredSize(new Dimension(W, H));        setOpaque(false);        setLayout(new BorderLayout());        update = new JButton("Update");        update.addActionListener(e->update());        add(update, BorderLayout.PAGE_START);        input  = new JTextField();        add(input, BorderLayout.PAGE_END);        text = "Enter text and press button";    }    private void update() {        text = input.getText();        input.setText("");        repaint();    }    @Override    public void paintComponent(final Graphics g) {        super.paintComponents(g);        final int width = getWidth();        final int height = getHeight();        g.setColor(Color.RED);        g.fillOval(width/2 - RADIUS, height/2 - RADIUS, RADIUS*2, RADIUS*2);        g.setColor(Color.BLUE);        g.drawString(text, height/2 - RADIUS - GAP, GAP);    }    public static void main(final String[] args) {        SwingUtilities.invokeLater(()->makeGui());    }    private static void  makeGui() {        JFrame frame = new JFrame();        frame.setLocationRelativeTo(null);        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);        frame.add(new DrawingPanel());        frame.pack();        frame.setVisible(true);    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java