0

我正在为我正在制作的音乐应用程序制作轨迹栏。基本上它是一个 Rectangle2D,它在 JPanel 扩展类“TrackBar”中水平移动,ActionListener 在另一个类“TrackBarAction”中,它由“TrackBar”类中的 Timer 移动,这次是在“Toolbar”类上启动的播放和暂停按钮在哪里。

  • 我遇到的问题是它不动。我将调试打印添加到控制台以查看它是否正在读取代码并且它是,除了它由于某种原因没有重新绘制(),所以它确实读取了代码但没有重新绘制()。

这是简化的代码:

public class Toolbar extends JPanel implements ActionListener {

public static boolean IS_PLAYING = false;

public Toolbar(){

      (...)

          pauseicon =  new ImageIcon(getClass().getResource("Icons/Pause.png"));    
          playicon = new ImageIcon(getClass().getResource("Icons/Play.png"));
          play = new JToggleButton(new ImageIcon(playicon.getImage().getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH)), false);            
        play.setOpaque(false);
        play.setContentAreaFilled(false);
        play.setBorderPainted(false);
        play.addItemListener ( new ItemListener( ) {

                @Override
                public void itemStateChanged(ItemEvent e) {
                    if(play.isSelected()){
                        play.setIcon((Icon)new ImageIcon(pauseicon.getImage().getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH)));
                        IS_PLAYING = true;
                        MainFrame.tb.t.start();     // THIS is where timer is called
                    } else {
                        play.setIcon((Icon)new ImageIcon(playicon.getImage().getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH)));
                        IS_PLAYING = false;
                        MainFrame.tb.t.stop();
                    }
                }});


        (...)

 } // end of constructor

} // end of class

下一个类是 Trackbar 类:

public class TrackBar extends JPanel{

private TrackBarAction tba = new TrackBarAction(this);
public static int TIME = 8;

public Timer t = new Timer(TIME, tba);
public static double x = 0, y = 0, velX = 0.5, velY = 0;


@Override
public void paintComponent(Graphics g){

    System.out.println("1"); // debug

            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D)g;
            //g2d.drawRect((int)x, (int)y, 10, 800);

            Rectangle2D r2d = new Rectangle2D.Double(x, y, 10.0, 800.0);  // x,x, w, h
            g2d.setPaint(Color.DARK_GRAY);
            g2d.fill(r2d);
            g2d.draw(r2d);

            System.out.println("2"); // debug
}

}

下一个类是具有动作侦听器的 TrackBarAction:

public class TrackBarAction implements ActionListener{

private TrackBar tb;

public TrackBarAction(TrackBar tb){

    this.tb = tb;
}

 @Override
public void actionPerformed(ActionEvent e) {
     System.out.println("3");

    // When it gets to the end, return to start point
        if(tb.x == 1024){
            tb.x = 0;
            tb.y = 0;
        }

        tb.x += tb.velX;
        tb.y += tb.velY;
        tb.repaint();
        System.out.println("4");
}

}

这是主框架:

public class MainFrame extends JFrame {

public static ColourToolbar colourBar;

public static TrackBar tb;

public MainFrame(){

    super("VIPE by Prestige WorldWide");

    // Top colour toolbar for tones
    colourBar = new ColourToolbar();
    this.getContentPane().add(colourBar, BorderLayout.NORTH);

    // The center where the drawing is done
    ImagePanel bg = new ImagePanel();   
        bg.setLayout(new BorderLayout());
        Dimension size = getPreferredSize();
        size.setSize(1024,800); //w, h
        bg.setPreferredSize(size);
    this.getContentPane().add(bg, BorderLayout.CENTER);

    tb = new TrackBar();
    bg.add(tb, BorderLayout.CENTER);

    //DrawBoard dboard =  new DrawBoard();
     //bg.add(dboard, BorderLayout.CENTER);

    //Image bgimage = (new ImageIcon(getClass().getResource("Icons/background.jpg"))).getImage();
    //JPanel bg = new JPanelWithBackground(bgimage);
    //this.getContentPane().add(bg, BorderLayout.CENTER);


    // The control toolbar where the settings and control buttons are.
    Toolbar toolBar = new Toolbar();
    this.getContentPane().add(toolBar, BorderLayout.SOUTH);
}

public static void main(String[] args){

    MainFrame frame = new MainFrame();

    frame.setBackground(Color.WHITE);
    frame.setSize(1024,768);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    //frame.pack();
    frame.setVisible(true);

}

}
4

2 回答 2

2

正如 MadProgrammer 指出的那样,您拥有的复杂的继承结构是不必要的。

破坏您发布的代码的是您的计时器正在操纵第二个屏幕外 TrackBar 的绘图坐标。由于您的 TrackBarAction 也是继承的 TrackBar,因此代码编译得很好,因为各种动画变量都存在。但是,它们属于未渲染的 TrackBar,而不是您实际使用的原始 TrackBar 实例。

    public class TrackBarAction implements ActionListener
{

private TrackBar tb;

public TrackBarAction( TrackBar tb )
{

    this.tb = tb;
}

@Override
public void actionPerformed( ActionEvent e )
{
    System.out.println( "3" );

    // When it gets to the end, return to start point
    if ( tb.x == 1024 ) {
    tb.x = 0;
    tb.y = 0;
    }

    tb.x += tb.velX;
    tb.y += tb.velY;
    tb.repaint();
    System.out.println( "4" );
}

}

编辑:这就是您更新后的 TrackBarAction 应该是什么样子。您在概念上的错误是您的 TrackBarAction 版本的原始实例变量是按值传递的,而不是像对象那样通过引用传递的概念。所以,你在你的版本中操作了错误的变量。

于 2013-02-28T23:02:49.477 回答
1

这个private static TrackBarAction tba = new TrackBarAction(new TrackBar());和这个

TrackBar tb = new TrackBar();
bg.add(tb, BorderLayout.CENTER);

是问题。拥有的引用TrackBarAction不再是屏幕上的引用。

以这种方式使用静态变量是糟糕的设计和有问题的......

public class TrackBar extends JPanel{

    private TrackBarAction tba;
    private int TIME = 8;

    private Timer t = new Timer(TIME, tba);
    private double x = 0, y = 0, velX = 0.5, velY = 0;

    public TrackBar() {
        tba =  = new TrackBarAction(this);
    }

    @Override
    public void paintComponent(Graphics g){
        System.out.println("1"); // debug

        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D)g;
        //g2d.drawRect((int)x, (int)y, 10, 800);

        Rectangle2D r2d = new Rectangle2D.Double(x, y, 10.0, 800.0);  // x,x, w, h
        g2d.setPaint(Color.DARK_GRAY);
        g2d.fill(r2d);
        g2d.draw(r2d);

        System.out.println("2"); // debug
    }
}

然后每个需要与之交互的类都TrackBar应该获得相同的实例(他们需要使用的实例)

于 2013-02-28T23:26:44.637 回答