简体   繁体   English

如何在调整面板大小时让JPanel记住用户绘制的图形?

[英]How to get JPanel to remember user-drawn graphics when panel is resized?

I'm trying to make a program that allows users to place music notes on staffs. 我正在尝试制作一个程序,允许用户在员工上放置音乐笔记。 There is a class called SheetMusicPane that extends JPanel, and it starts out with a bunch of staffs drawn from top to bottom. 有一个名为SheetMusicPane的类扩展了JPanel,它从一堆从上到下绘制的人员开始。 By clicking on the buttons in the toolbar at the top, users can choose notes to draw. 通过单击顶部工具栏中的按钮,用户可以选择要绘制的注释。 There is also a button on the toolbar that allows the user to increase the amount of sheet music available (the SheetMusicPane is set inside a JScrollPane). 工具栏上还有一个按钮,允许用户增加可用的乐谱量(SheetMusicPane在JScrollPane中设置)。 I don't know how to make the music notes copy over when the user resizes the SheetMusicPane. 当用户调整SheetMusicPane的大小时,我不知道如何使音符复制。 The initial staffs stay put, however. 然而,最初的员工仍然存在。

I tried the JPanel.repaint() method; 我尝试了JPanel.repaint()方法; it didn't work. 它不起作用。

The resizing is pretty simple: 调整大小非常简单:

JButton moreMusicButton = new JButton("Get More Sheet Music");
    tb.add(moreMusicButton);
    moreMusicButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
           smp.setPreferredSize(new Dimension(scrollSize.width, smp.getHeight() +     moreMusicAmount));
           smp.repaint();
        }
    });

As said above, repaint() isn't doing anything. 如上所述,repaint()没有做任何事情。

Thanks in advance! 提前致谢!

Adding note-drawing code: 添加笔记绘图代码:

The note-drawing buttons each call this method (the String "note" is obtained from the button's ActionCommand): 每个音符绘制按钮都调用此方法(字符串“note”是从按钮的ActionCommand获得的):

  public void getShape(final Graphics g, final String note) {
     MouseListener[] listeners = this.getMouseListeners();
     for (MouseListener ml : listeners) {
        this.removeMouseListener(ml);  //makes graphics stop drawing previous note
     }
     this.addMouseListener(new MouseListener() {
        public void mousePressed(MouseEvent e) {
        }
        public void mouseReleased(MouseEvent e) {
        }
        public void mouseEntered(MouseEvent e) {
        }
        public void mouseExited(MouseEvent e) {
        }
        public void mouseClicked(MouseEvent e) {
           Point p = MouseInfo.getPointerInfo().getLocation();
           addShape(g, p.x, p.y, note);
           int pitch = 12;
           piano.playNote(pitch);
           advance(1.0, piano);
           try { addToFile(pitch, note);}
           catch(FileNotFoundException fnfe) {}
           catch(IOException ioe) {}
        }
     });
  }

Here's how the panel itself is created. 这是面板本身的创建方式。 It comprises a set of private nested classes and it starts out showing plain, note-free sheet music. 它包含一组私有嵌套类,它开始显示简单,无音符的乐谱。

private class SheetMusicPane extends JPanel { 私有类SheetMusicPane扩展JPanel {

  public SheetMusicPane() {
     final Graphics g = this.getGraphics();  
  } 

  //paints staffs
  public void paint(Graphics g) {
     super.paintComponent(g);
     for (int i = 0; (i - 1)*staffWidth < scrollSize.height + 100; i++) {
        int y = paddingNorth + i*staffWidth;
        Staff staff = new Staff(g, y, "treble");
     }
  }

  public void paintComponent(Graphics g) {
     super.paintComponent(g);
     for (String note : noteList) {
        addShape(g, 100, 200, note); 
     }
  }

  //takes in mouse info and calls addShape to draw notes on clicks
  public void getShape(final Graphics g, final String note) {  ... } //as shown above

  //draws a note
  private void addShape(Graphics g, int x, int y, String note) { ... }

  private void addToFile(int pitch, String note) throws FileNotFoundException, IOException { ...//adds note info to a file }

//just makes a five-line staff at this point private class Staff { //此时只需要一个五线工作人员私人班级员工{

  private Graphics g;
  private int y;
  private int[] pitches;

  public Staff(Graphics g, int y, String cleff) {  ...//draws the lines }

} }

you need to override the paintComponent method of your Panel. 您需要覆盖Panel的paintComponent方法。 You save everything to paint in an Array (or List) and the paintComponent method draws them. 您可以将所有内容保存到Array(或List)中,并且paintComponent方法会绘制它们。 (on every repaint). (在每次重画上)。

If you draw them on click, the next time repaint() is called the Panel will be cleared and repainted using the paintComponent Method. 如果在单击时绘制它们,则下次调用repaint()时,将使用paintComponent方法清除并重新绘制Panel。 Your drawings are as long on the Panel as reapaint() is not called. 您的绘图在Panel上的长度与reapaint()未被调用一样长。

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

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