加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

绘制所有其他组件(Swing,Java)

发布时间:2020-12-15 04:56:15 所属栏目:Java 来源:网络整理
导读:在我的应用程序中,我需要像Photoshop那样绘制网格线 – 例如,用户可以在文档上拖动线条以帮助他对齐图层.现在,问题在于我能够绘制这样的线条(它只是简单的使用Line2D的简单 Java2D绘画),但我无法将这些线条放在其他所有内容之上,因为当子组件绘制自己时,我的
在我的应用程序中,我需要像Photoshop那样绘制网格线 – 例如,用户可以在文档上拖动线条以帮助他对齐图层.现在,问题在于我能够绘制这样的线条(它只是简单的使用Line2D的简单 Java2D绘画),但我无法将这些线条放在其他所有内容之上,因为当子组件绘制自己时,我的网格线被删除了.

程序结构是这样的:JFrame – > JPanel – > JScrollPane – > JPanel – > [许多其他JPanels,就像层]

作为测试,我将绘制代码添加到JFrame,它正确显示我的Line2D实例在其他所有内容之上.但是,当我在子组件中执行任何需要该子项重新绘制的内容时,JFrame中绘制的线将被删除.

我知道这是预期的Swing行为 – 也就是说,它只会重绘那些已经改变的区域.但是,我正在寻找一些方法,不断在其他所有方面绘制线网格线.

我能够让它工作的唯一方法是使用一个Swing Timer,它每隔10ms在我的根组件上调用repaint(),但它消耗了大量的CPU.

UPDATE
下面是一个例子的工作代码.请注意,在我的实际应用程序中,我有许多可以触发重绘()的不同组件,并且没有一个组件引用了执行网格线绘制的组件(当然我可以将它传递给每个人,但是成为最新的选择)

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GridTest extends JFrame {
    public static void main(String[] args) {
        new GridTest().run();
    }

    private void run() {
        setLayout(null);
        setPreferredSize(new Dimension(200,200));
        setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);

        final JPanel p = new JPanel();
        p.setBounds(20,20,100,100);
        p.setBackground(Color.white);
        add(p);

        JButton b = new JButton("Refresh");
        b.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // When I call repaint() here,the paint() method of
                // JFrame it's not called,thus resulting in part of the
                // red line to be erased / overridden.

                // In my real application application,I don't have
                // easy access to the component that draws the lines
                p.repaint();
            }
        });
        b.setBounds(0,150,30);
        add(b);

        pack();
        setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D gg = (Graphics2D)g.create();
        Line2D line = new Line2D.Double(0,50,getWidth(),50);
        gg.setStroke(new BasicStroke(3));
        gg.setColor(Color.red);
        gg.draw(line);
        gg.dispose();
    }
}

解决方法

如果要绘制放置到JScrollPane的JComponents,那么可以绘制到JViewPort,例如 here

编辑:

1)因为你的代码被绘制到错误的容器,到JFrame,肯定可以绘制到JFrame,但你必须提取RootPane or GlassPane

2)你必须学习如何LayoutManagers工作,我让你的代码与原始大小,不好,非常糟糕

3)绘制到GlassPane或JViewPort

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import javax.swing.*;

public class GridTest extends JFrame {
    private static final long serialVersionUID = 1L;

    public static void main(String[] args) {
        new GridTest().run();
    }

    private void run() {
        setLayout(null);
        setPreferredSize(new Dimension(200,200));
        setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);

        final JPanel p = new JPanel() {
            private static final long serialVersionUID = 1L;

            @Override
            public void paint(Graphics g) {

                super.paint(g);
                Graphics2D gg = (Graphics2D) g.create();
                Line2D line = new Line2D.Double(0,50);
                gg.setStroke(new BasicStroke(3));
                gg.setColor(Color.red);
                gg.draw(line);
                //gg.dispose();

            }
        };
        p.setBounds(20,100);
        p.setBackground(Color.white);
        add(p);

        JButton b = new JButton("Refresh");
        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                p.repaint();
            }
        });
        b.setBounds(0,30);
        add(b);

        pack();
        setVisible(true);
    }
}

编辑:2,如果你期望单行,在固定的界限上

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import javax.swing.*;
import javax.swing.border.LineBorder;

public class GridTest extends JFrame {
    private static final long serialVersionUID = 1L;

    public static void main(String[] args) {
        new GridTest().run();
    }

    private void run() {
        setPreferredSize(new Dimension(200,200));
        setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);

        final JPanel p = new JPanel() {
            private static final long serialVersionUID = 1L;

            @Override
            public void paint(Graphics g) {
                super.paint(g);
                Graphics2D gg = (Graphics2D) g.create();
                Line2D line = new Line2D.Double(0,50);
                gg.setStroke(new BasicStroke(3));
                gg.setColor(Color.red);
                gg.draw(line);
                gg.dispose();
            }
        };
        JPanel p1 = new JPanel();
        p1.setBorder(new LineBorder(Color.black,1));
        JPanel p2 = new JPanel();
        p2.setBorder(new LineBorder(Color.black,1));
        JPanel p3 = new JPanel();
        p3.setBorder(new LineBorder(Color.black,1));
        p.setLayout(new GridLayout(3,0));
        p.add(p1);
        p.add(p2);
        p.add(p3);
        p.setBounds(20,100);
        p.setBackground(Color.white);
        add(p,BorderLayout.CENTER);

        JButton b = new JButton("Refresh");
        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                p.repaint();
            }
        });
        add(b,BorderLayout.SOUTH);

        pack();
        setVisible(true);
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读