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

时间:2014-02-25 21:27:36

标签: java swing graphics jpanel

我试图制作一个程序,允许用户在员工身上放置音乐笔记。有一个名为SheetMusicPane的类扩展了JPanel,它从一堆从上到下绘制的人员开始。通过单击顶部工具栏中的按钮,用户可以选择要绘制的注释。工具栏上还有一个按钮,允许用户增加可用的乐谱量(SheetMusicPane在JScrollPane中设置)。当用户调整SheetMusicPane的大小时,我不知道如何使音符复制。然而,最初的员工仍然存在。

我尝试了JPanel.repaint()方法;它没有用。

调整大小非常简单:

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();
        }
    });

如上所述,重绘()并没有做任何事情。

提前致谢!

添加笔记代码:

每个音符绘制按钮都调用此方法(字符串"音符") 来自按钮的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) {}
        }
     });
  }

以下是面板本身的创建方式。它包含一组私有嵌套类,它开始显示简单,无音符的乐谱。

私有类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 }

//此时只需要一个五线工作人员    私人班级员工{

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

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

}

1 个答案:

答案 0 :(得分:2)

您需要覆盖Panel的paintComponent方法。 您可以将所有内容保存到Array(或List)中,并且paintComponent方法会绘制它们。 (每次重画)。

如果您在单击时绘制它们,则下次调用repaint()时,将使用paintComponent方法清除并重新绘制Panel。您的绘图在Panel上的长度与reapaint()不一样。