关于Jpanel的paintComponent函数绘图时的奇怪现象!感兴趣的进

时间:2021-08-13 06:13:42
下面的代码是在JTabbedPane上面的一个Jpanel上画图,可以运行,但结果好怪异,请高手指教是怎么回事。
布局管理器是BorderLayout,左边红的是一个Jpanel;右面是自己定义的一个JPanel的子类,要在它上面画图,可是显示不出来。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

public class TestDemo2 extends JFrame{
public JTabbedPane jtp = new JTabbedPane();
public MyJPanel2 jp;

public TestDemo2(){
jp = new MyJPanel2();
jtp.add("物资态势图", jp);
this.getContentPane().add(jtp);

this.setVisible(true);
this.setSize(900, 600);
this.validate();
}
public static void main(String[] args) {
new TestDemo2();
}
}
class MyJPanel2 extends JPanel implements ActionListener{
public JLabel jl = new JLabel("请输入要追踪的货物ID号:");
public JTextField jtf = new JTextField(10);
public JButton jbtn = new JButton("查询");
public JPanel j1;
public MyDrawPanel j2;
public MyJPanel2() {
this.setLayout(new BorderLayout());
this.add(getHeader(), BorderLayout.NORTH);

j1 = new JPanel();
j1.setBackground(Color.RED);
j2 = new MyDrawPanel();
j2.setBackground(Color.white);
this.add(getCenter(), BorderLayout.CENTER);
}
public JComponent getHeader() {
JPanel p1 = new JPanel();
p1.setLayout(new FlowLayout());
p1.add(jl);
p1.add(jtf);
jbtn.addActionListener(this);
p1.add(jbtn);
return p1;
}
public JComponent getCenter() {
JPanel p2 = new JPanel();
p2.setLayout(new GridLayout(1, 2));
p2.add(new JScrollPane(j1));
p2.add(j2);
return p2;
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == this.jbtn){
j2.draw(this.getGraphics());
}
}
}
class MyDrawPanel extends JPanel{
public MyDrawPanel(){
super();
}
public void paintComponent(Graphics g){
                  //super.paintComponent(g);//这句话不写面板的白色背景就显不出来,为什么涅。。。
g = this.getGraphics();
g.setColor(Color.BLUE);//下面的画图显示不出来。。。
g.fillOval(this.getX(), this.getY()+50, this.getX()+50, this.getY()+50);
System.out.println(this.getSize());
System.out.println(this.getX() +"  "+this.getY());
}
public void draw(Graphics g){
repaint();
}
}

4 个解决方案

#1


两个问题造成的,都在paintComponent方法里面
第一:
g = this.getGraphics();
这句要移除掉,g对象应该使用方法参数里面的那个,是绘制系统帮你准备好了的。
第二:
g.fillOval(this.getX(), this.getY()+50, this.getX()+50, this.getY()+50);
你这句的本意是希望在drawPanel左上角画一个圆是吧。但是这里前面两个参数给的不太对,这里的this.getX()和this.getY()得到的是你这个drawPanel在父组件中的坐标。你本来想得到的效果应该将这句改为
g.fillOval(0, 0+50, this.getX()+50, this.getY()+50);
试试对不对,随时发问吧!

#2




/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 2011-10-1
 * Time: 23:05:26
 * To change this template use File | Settings | File Templates.
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

public class TestDemo2 extends JFrame{
    public JTabbedPane jtp = new JTabbedPane();
    public MyJPanel2 jp;

    public TestDemo2(){
        jp = new MyJPanel2();
        jtp.add("物资态势图", jp);
        this.getContentPane().add(jtp);


        this.setSize(900, 600);
        this.setVisible(true);
        this.validate();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        new TestDemo2();
    }
}
class MyJPanel2 extends JPanel implements ActionListener{
    public JLabel jl = new JLabel("请输入要追踪的货物ID号:");
    public JTextField jtf = new JTextField(10);
    public JButton jbtn = new JButton("查询");
    public JPanel j1;
    public MyDrawPanel j2;
    public MyJPanel2() {
        this.setLayout(new BorderLayout());
        this.add(getHeader(), BorderLayout.NORTH);

        j1 = new JPanel();
        j1.setBackground(Color.RED);
        j2 = new MyDrawPanel();
        j2.setBackground(Color.white);
        //添加j2
        this.add(getCenter(), BorderLayout.CENTER);
    }
    public JComponent getHeader() {
        JPanel p1 = new JPanel();
        p1.setLayout(new FlowLayout());
        p1.add(jl);
        p1.add(jtf);
        jbtn.addActionListener(this);
        p1.add(jbtn);
        return p1;
    }
    public JComponent getCenter() {
        JPanel p2 = new JPanel();
        p2.setLayout(new GridLayout(1, 2));
        p2.add(new JScrollPane(j1));
        p2.add(j2);
        return p2;
    }
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == this.jbtn){
            j2.draw(this.getGraphics());
        }
    }
}
class MyDrawPanel extends JPanel{
    public MyDrawPanel(){
        super();
    }
    @Override
    public void paintComponent(Graphics g){
        //下面这一句在覆盖paintConponent的时候都要写上
        //调用父类的paintComponent(g)方法,清空并重绘面板
        super.paintComponent(g);//这句话不写面板的白色背景就显不出来,为什么涅。。。
//        g = this.getGraphics(); //这句注解掉,用参数列表的g对象画图
        g.setColor(Color.BLUE);//下面的画图显示不出来。。。
        g.drawLine(0,0,50,50);
        g.fillOval(0, 50, 50, 50);
        System.out.println("size:"+this.getSize());
//        System.out.println(this.getX() +" "+this.getY());
    }
    public void draw(Graphics g){
        repaint();
    }
}


#3


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

public class TestDemo2 extends JFrame{
    private JTabbedPane jtp = new JTabbedPane();
    private MyJPanel2 jp;

    public TestDemo2(){
        super("物资态势图");
        jp = new MyJPanel2();
        jtp.add("物资态势图", jp);
        this.getContentPane().add(jtp);
        this.setSize(900, 600);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new java.lang.Runnable(){
                @Override public void run(){
                    new TestDemo2();
                }
            });
    }

    static class MyJPanel2 extends JPanel implements ActionListener{
        private JLabel jl = new JLabel("请输入要追踪的货物ID号:");
        private JTextField jtf = new JTextField(10);
        private JButton jbtn = new JButton("查询");
        private JPanel j1;
        private MyDrawPanel j2;
        public MyJPanel2() {
            super(new BorderLayout());
            this.add(getHeader(), BorderLayout.NORTH);
            this.add(getCenter(), BorderLayout.CENTER);
        }
        private JComponent getHeader() {
            JPanel p1 = new JPanel();
            p1.add(jl);
            p1.add(jtf);
            jbtn.addActionListener(this);
            p1.add(jbtn);
            return p1;
        }
        private JComponent getCenter() {
            JPanel p2 = new JPanel();
            p2.setLayout(new GridLayout(1, 2));
            j1 = new JPanel();
            j1.setBackground(Color.RED);
            j2 = new MyDrawPanel();
            j2.setBackground(Color.WHITE);
            p2.add(new JScrollPane(j1));
            p2.add(j2);
            return p2;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if(e.getSource() == this.jbtn){
                j2.repaint();
            }
        }
    }

    static class MyDrawPanel extends JPanel {
        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);//这句话不写面板的白色背景就显不出来,为什么涅。。。不写就是自己绘制组件内容,没有使用setBackground设置的背景。
            Graphics2D g2d = (Graphics2D)g;
            g2d.setPaint(Color.BLUE);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.fillOval(0, 50, 50, 50);
        }
    }
}

#4


请教一下,是不是paint(Graphics g)函数画图时,必须占满整个JFram或者JPanel,谢谢

#1


两个问题造成的,都在paintComponent方法里面
第一:
g = this.getGraphics();
这句要移除掉,g对象应该使用方法参数里面的那个,是绘制系统帮你准备好了的。
第二:
g.fillOval(this.getX(), this.getY()+50, this.getX()+50, this.getY()+50);
你这句的本意是希望在drawPanel左上角画一个圆是吧。但是这里前面两个参数给的不太对,这里的this.getX()和this.getY()得到的是你这个drawPanel在父组件中的坐标。你本来想得到的效果应该将这句改为
g.fillOval(0, 0+50, this.getX()+50, this.getY()+50);
试试对不对,随时发问吧!

#2




/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 2011-10-1
 * Time: 23:05:26
 * To change this template use File | Settings | File Templates.
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

public class TestDemo2 extends JFrame{
    public JTabbedPane jtp = new JTabbedPane();
    public MyJPanel2 jp;

    public TestDemo2(){
        jp = new MyJPanel2();
        jtp.add("物资态势图", jp);
        this.getContentPane().add(jtp);


        this.setSize(900, 600);
        this.setVisible(true);
        this.validate();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        new TestDemo2();
    }
}
class MyJPanel2 extends JPanel implements ActionListener{
    public JLabel jl = new JLabel("请输入要追踪的货物ID号:");
    public JTextField jtf = new JTextField(10);
    public JButton jbtn = new JButton("查询");
    public JPanel j1;
    public MyDrawPanel j2;
    public MyJPanel2() {
        this.setLayout(new BorderLayout());
        this.add(getHeader(), BorderLayout.NORTH);

        j1 = new JPanel();
        j1.setBackground(Color.RED);
        j2 = new MyDrawPanel();
        j2.setBackground(Color.white);
        //添加j2
        this.add(getCenter(), BorderLayout.CENTER);
    }
    public JComponent getHeader() {
        JPanel p1 = new JPanel();
        p1.setLayout(new FlowLayout());
        p1.add(jl);
        p1.add(jtf);
        jbtn.addActionListener(this);
        p1.add(jbtn);
        return p1;
    }
    public JComponent getCenter() {
        JPanel p2 = new JPanel();
        p2.setLayout(new GridLayout(1, 2));
        p2.add(new JScrollPane(j1));
        p2.add(j2);
        return p2;
    }
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == this.jbtn){
            j2.draw(this.getGraphics());
        }
    }
}
class MyDrawPanel extends JPanel{
    public MyDrawPanel(){
        super();
    }
    @Override
    public void paintComponent(Graphics g){
        //下面这一句在覆盖paintConponent的时候都要写上
        //调用父类的paintComponent(g)方法,清空并重绘面板
        super.paintComponent(g);//这句话不写面板的白色背景就显不出来,为什么涅。。。
//        g = this.getGraphics(); //这句注解掉,用参数列表的g对象画图
        g.setColor(Color.BLUE);//下面的画图显示不出来。。。
        g.drawLine(0,0,50,50);
        g.fillOval(0, 50, 50, 50);
        System.out.println("size:"+this.getSize());
//        System.out.println(this.getX() +" "+this.getY());
    }
    public void draw(Graphics g){
        repaint();
    }
}


#3


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

public class TestDemo2 extends JFrame{
    private JTabbedPane jtp = new JTabbedPane();
    private MyJPanel2 jp;

    public TestDemo2(){
        super("物资态势图");
        jp = new MyJPanel2();
        jtp.add("物资态势图", jp);
        this.getContentPane().add(jtp);
        this.setSize(900, 600);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new java.lang.Runnable(){
                @Override public void run(){
                    new TestDemo2();
                }
            });
    }

    static class MyJPanel2 extends JPanel implements ActionListener{
        private JLabel jl = new JLabel("请输入要追踪的货物ID号:");
        private JTextField jtf = new JTextField(10);
        private JButton jbtn = new JButton("查询");
        private JPanel j1;
        private MyDrawPanel j2;
        public MyJPanel2() {
            super(new BorderLayout());
            this.add(getHeader(), BorderLayout.NORTH);
            this.add(getCenter(), BorderLayout.CENTER);
        }
        private JComponent getHeader() {
            JPanel p1 = new JPanel();
            p1.add(jl);
            p1.add(jtf);
            jbtn.addActionListener(this);
            p1.add(jbtn);
            return p1;
        }
        private JComponent getCenter() {
            JPanel p2 = new JPanel();
            p2.setLayout(new GridLayout(1, 2));
            j1 = new JPanel();
            j1.setBackground(Color.RED);
            j2 = new MyDrawPanel();
            j2.setBackground(Color.WHITE);
            p2.add(new JScrollPane(j1));
            p2.add(j2);
            return p2;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if(e.getSource() == this.jbtn){
                j2.repaint();
            }
        }
    }

    static class MyDrawPanel extends JPanel {
        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);//这句话不写面板的白色背景就显不出来,为什么涅。。。不写就是自己绘制组件内容,没有使用setBackground设置的背景。
            Graphics2D g2d = (Graphics2D)g;
            g2d.setPaint(Color.BLUE);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.fillOval(0, 50, 50, 50);
        }
    }
}

#4


请教一下,是不是paint(Graphics g)函数画图时,必须占满整个JFram或者JPanel,谢谢