【问题标题】:calling a java method to draw graphics调用java方法绘制图形
【发布时间】:2012-11-07 18:46:43
【问题描述】:

我正在尝试在框架上绘制一些简单的图形。我还希望能够调整我从主要方法中绘制的内容。例如,设置要打印的字符串变量,或者矩形的坐标。

我似乎遇到的问题是在我设置类变量之前调用了paintComponent 方法。我将如何更改此代码以便能够在绘制到屏幕之前设置JPanel/JFrame 变量?

谢谢

import java.awt.*;
import javax.swing.*;

public class Test {

    public static void main(String[] args) {
        FrameTest test_frame = new FrameTest();
        test_frame.test_string = "I WANT TO DRAW THIS STRING";
    }
}

class FrameTest extends JFrame{
    private static final long serialVersionUID = 1L;
    String test_string;

    public FrameTest(){
        this.test_string = "TEMP STRING FROM FRAME";
        JFrame gui = new JFrame();
        gui.setTitle("Test Title");
        gui.setSize(400,400);
        gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Painting painting = new Painting();

        Container pane = gui.getContentPane();
        pane.setLayout(new GridLayout(1,1));

        pane.add(painting);
        gui.setVisible(true);

    }
}

class Painting extends JPanel{
    private static final long serialVersionUID = 1L;
    String test_string;

    public Painting(){
        setBackground(Color.WHITE);
        this.test_string = "TEMP STRING FROM PANEL";
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setColor(Color.RED);
        g.drawString(test_string, 20, 20);
    }
}

【问题讨论】:

  • if (test_String != null) g.drawString(test_string, 20, 20); 并且可能更改为AtomicReference<String> test_string,请参阅AtomicReference
  • 不要以为你对绘画过程有任何控制权,你没有。您可以向重绘管理器提出更新建议,仅此而已。在您的情况下,JoopEggen 和 Reimeus 的建议都将帮助您解决问题(无论如何,您应该始终检查 null - 恕我直言)

标签: java swing graphics


【解决方案1】:

在这里,您将一个字符串分配给FrameTest 中的test_string,它不会更新Painting 中的同名变量:

test_frame.test_string = "I WANT TO DRAW THIS STRING";

为什么不向FrameTest 添加更新方法,因为您对此有参考:

public void setTestString(String test_string) {
    painting.setTestString(test_string);
}

然后调用:

FrameTest test_frame = new FrameTest();
test_frame.setTestString("I WANT TO DRAW THIS STRING");

注意:Java 使用 CamelCase,例如testString

【讨论】:

    【解决方案2】:

    您可以通过构造函数将要绘制的文本传递给Painting 类,并以同样的方式将绘画传递给FrameSet。

    要了解有关 java 构造函数和参数的更多信息,请阅读:http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

    我已经修改了你的代码来满足你的需要,不过我还没有测试过。

    import java.awt.*;
    import javax.swing.*;
    
    public class Test {
    
        public static void main(String[] args) {
            Painting painting = new Painting("I WANT TO DRAW THIS STRING");
            FrameTest test_frame = new FrameTest(painting);
        }
    }
    
    class FrameTest extends JFrame{
        private static final long serialVersionUID = 1L;
        String test_string;
    
        public FrameTest(painting){
            super();
            this.test_string = "TEMP STRING FROM FRAME";
            JFrame gui = new JFrame();
            gui.setTitle("Test Title");
            gui.setSize(400,400);
            gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            Container pane = gui.getContentPane();
            pane.setLayout(new GridLayout(1,1));
    
            pane.add(painting);
            gui.setVisible(true);
    
        }
    }
    
    class Painting extends JPanel{
        private static final long serialVersionUID = 1L;
        String test_string;
    
        public Painting(String test_string){
            super();
            this.test_string = test_string;
            setBackground(Color.WHITE);
        }
    
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            g.setColor(Color.RED);
            g.drawString(test_string, 20, 20);
        }
    }
    

    【讨论】:

      【解决方案3】:

      从 FrameTest 类中删除 test_string。直接使用 set 方法设置 test_string。见例子:

      import java.awt.Color;
      import java.awt.Container;
      import java.awt.Graphics;
      import java.awt.GridLayout;
      
      import javax.swing.JFrame;
      import javax.swing.JPanel;
      
      public class Test {
      
          public static void main(String[] args) {
              FrameTest1 test_frame = new FrameTest1();
              test_frame.setContentString("I WANT TO DRAW THIS STRING");
          }
      
      }
      
      class FrameTest1 extends JFrame {
          private static final long serialVersionUID = 1L;
      
          Painting painting = new Painting();
      
          public FrameTest1() {
              JFrame gui = new JFrame();
              gui.setTitle("Test Title");
              gui.setSize(400, 400);
              gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
              Container pane = gui.getContentPane();
              pane.setLayout(new GridLayout(1, 1));
      
              pane.add(painting);
              gui.setVisible(true);
      
          }
      
          public void setContentString(String value) {
              painting.test_string = value;
          }
      }
      
      class Painting extends JPanel {
          private static final long serialVersionUID = 1L;
          String test_string;
      
          public Painting() {
              setBackground(Color.WHITE);
              this.test_string = "TEMP STRING FROM PANEL";
          }
      
          public void paintComponent(Graphics g) {
              super.paintComponent(g);
      
              g.setColor(Color.RED);
              g.drawString(test_string, 20, 20);
          }
      }
      

      【讨论】:

        【解决方案4】:

        例如设置要打印的String变量,或者矩形的坐标。

        main(String[]) 中创建一个BufferedImage,有一个Painting.setImage(Image) 的方法,在JLabel 中显示图像。

        这更加通用,因为它可以接受字符串的图像,或椭圆的图像,或在渐变 BG 上的椭圆的一部分上的字符串的图像..

        显示许多图像

        import java.awt.*;
        import java.awt.event.*;
        import java.awt.image.BufferedImage;
        import javax.swing.*;
        import javax.swing.border.EmptyBorder;
        import java.util.Random;
        
        public class ImageViewer {
            
            JPanel gui;
            /** Displays the image. */
            JLabel imageCanvas;
        
            /** Set the image as icon of the image canvas (display it). */
            public void setImage(Image image) {
                imageCanvas.setIcon(new ImageIcon(image));
            }
            
            public void initComponents() {
                if (gui==null) { 
                    gui = new JPanel(new BorderLayout());
                    gui.setBorder(new EmptyBorder(5,5,5,5));
                    imageCanvas = new JLabel();
                    
                    JPanel imageCenter = new JPanel(new GridBagLayout());
                    imageCenter.add(imageCanvas);
                    JScrollPane imageScroll = new JScrollPane(imageCenter);
                    imageScroll.setPreferredSize(new Dimension(300,100));
                    gui.add(imageScroll, BorderLayout.CENTER);
                }
            }
            
            public Container getGui() {
                initComponents();
                return gui;
            }
            
            public static Image getRandomImage(Random random) {
                int w = 100 + random.nextInt(400);
                int h = 50 + random.nextInt(200);
                BufferedImage bi = new BufferedImage(
                        w,h,BufferedImage.TYPE_INT_RGB);
                
                return bi;
            }
        
            public static void main(String[] args) throws Exception {
                Runnable r = new Runnable() {
                    @Override
                    public void run() {
                        JFrame f = new JFrame("Image Viewer");
                        // TODO Fix kludge to kill the Timer
                        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    
                        final ImageViewer viewer = new ImageViewer();
                        f.setContentPane(viewer.getGui());
                        
                        f.pack();
                        f.setLocationByPlatform(true);
                        f.setVisible(true);
        
                        ActionListener animate = new ActionListener() {
        
                            Random random = new Random();
                            
                            @Override
                            public void actionPerformed(ActionEvent arg0) {
                                viewer.setImage(getRandomImage(random));
                            }
                        };
                        Timer timer = new Timer(1500,animate);
                        timer.start();
                    }
                };
                SwingUtilities.invokeLater(r);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多