如何实现JScrollPane的图形?

时间:2016-01-19 23:48:07

标签: java swing user-interface jframe jscrollpane

目标是在窗口上绘制几十万条垂直线,因此我需要一个滚动条,缩小不是一个选项,因为分隔每条线的空间甚至不是一个像素。我采用了在类中使用paint方法并将类和JScrollPane添加到JFrame的方法。没有解决这就是为什么我采用NetBeans JFrame表单的方法。基本上,如何将我的图形方法实现到具有滚动条的面板中?我遇到的问题是我的值正在打印机就好了,但根本没有窗口出现。如果需要任何其他信息,请与我们联系。感谢。

public class PedroGUI extends javax.swing.JFrame {
    public PedroGUI() {
        initComponents();
        draw();
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        scroll = new javax.swing.JScrollPane();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        scroll.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        scroll.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(scroll, javax.swing.GroupLayout.PREFERRED_SIZE, 429, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(123, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(scroll, javax.swing.GroupLayout.PREFERRED_SIZE, 267, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(86, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        


    public void draw() {
        Graphics g = scroll.getGraphics();
        g.setColor(Color.red);
        int bytes, samples, frequency;
        try {
            FileInputStream fis = new FileInputStream("./pepe.wav");
            BufferedInputStream bis = new BufferedInputStream(fis);
            byte[] data = new byte[128];
            bis.skip(44);
            samples = 0;
            while ((bytes = bis.read(data)) > 0) {
                for (int i = 0; i < bytes; i++) {
                    frequency = data[i] & 0xFF; 
                    System.out.println(samples + " " + frequency);
                    g.drawLine(samples, frequency + 300, samples, -frequency + 300);
                    samples++;
                }

            }
            bis.read(data);
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                PedroGUI a = new PedroGUI();
                a.draw();
            }
        });
    }

    private javax.swing.JScrollPane scroll;

}

1 个答案:

答案 0 :(得分:3)

绘画通常是通过覆盖基于paintComponent的类的JComponent来实现的。您不想做的是尝试覆盖paint/paintComponent的{​​{1}},并且肯定不会使用JScrollPane

getGraphics返回最后绘制到组件上的东西的快照,如果你尝试绘制到它,它将在下次绘制组件时丢弃,因为Swing使用被动渲染算法,这可以立即完成,也可以在将来的某个随机时间完成(这就是为什么你应该使用getGraphics

绘画也是破坏性的,也就是说,你需要从头开始重新绘制组件的状态。

paintComponent也是一个复合组件,也就是说,有许多其他组件用于实现它的功能(即JScrollPane

JScrollPane

你应该做的是创建一个自定义组件,从JViewport扩展,并覆盖它的JPanel方法并从中生成你的图形。

Graph

此示例还使用paintComponent接口,该接口允许Scrollable最初布局小于组件的首选大小,这很好,因为组件可能非常宽。

这个例子也只是生成一个简单的直方图,但你得到了jist

JScrollPane

有关详细信息,请参阅Painting in AWT and SwingPerforming Custom PaintingHow to Use Scroll Panes