2D-график в jPanel в Netbeans - PullRequest
       5

2D-график в jPanel в Netbeans

3 голосов
/ 07 декабря 2010

У меня вопрос по поводу некоторой примитивной графики.Я новичок в Java-графике и графическом построении в целом, поэтому у меня много вопросов.
Я использую Netbeans 6.9.1.В основном, есть главная рама и панель внутри.Я хочу нарисовать график внутри панели.Ну, вопрос в том, чтобы сделать это?Ниже приведен код для трех классов (в основном сгенерированный автоматически):

   package graphics;

import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
 * The application's main frame.
 */
public class GraphicsView extends FrameView {

public GraphicsView(SingleFrameApplication app) {
    super(app);

    initComponents();

    jPanel1.add(new Graph());

    // status bar initialization - message timeout, idle icon and busy animation, etc
    ResourceMap resourceMap = getResourceMap();
    int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
    messageTimer = new Timer(messageTimeout, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            statusMessageLabel.setText("");
        }
    });
    messageTimer.setRepeats(false);
    int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
    for (int i = 0; i < busyIcons.length; i++) {
        busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
    }
    busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
            statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
        }
    });
    idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
    statusAnimationLabel.setIcon(idleIcon);
    progressBar.setVisible(false);

    // connecting action tasks to status bar via TaskMonitor
    TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
    taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
        public void propertyChange(java.beans.PropertyChangeEvent evt) {
            String propertyName = evt.getPropertyName();
            if ("started".equals(propertyName)) {
                if (!busyIconTimer.isRunning()) {
                    statusAnimationLabel.setIcon(busyIcons[0]);
                    busyIconIndex = 0;
                    busyIconTimer.start();
                }
                progressBar.setVisible(true);
                progressBar.setIndeterminate(true);
            } else if ("done".equals(propertyName)) {
                busyIconTimer.stop();
                statusAnimationLabel.setIcon(idleIcon);
                progressBar.setVisible(false);
                progressBar.setValue(0);
            } else if ("message".equals(propertyName)) {
                String text = (String)(evt.getNewValue());
                statusMessageLabel.setText((text == null) ? "" : text);
                messageTimer.restart();
            } else if ("progress".equals(propertyName)) {
                int value = (Integer)(evt.getNewValue());
                progressBar.setVisible(true);
                progressBar.setIndeterminate(false);
                progressBar.setValue(value);
            }
        }
    });
}

@Action
public void showAboutBox() {
    if (aboutBox == null) {
        JFrame mainFrame = GraphicsApp.getApplication().getMainFrame();
        aboutBox = new GraphicsAboutBox(mainFrame);
        aboutBox.setLocationRelativeTo(mainFrame);
    }
    GraphicsApp.getApplication().show(aboutBox);
}

/** This method is called from within the constructor to
 * initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is
 * always regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

    mainPanel = new javax.swing.JPanel();
    jPanel1 = new javax.swing.JPanel();
    menuBar = new javax.swing.JMenuBar();
    javax.swing.JMenu fileMenu = new javax.swing.JMenu();
    javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
    javax.swing.JMenu helpMenu = new javax.swing.JMenu();
    javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
    statusPanel = new javax.swing.JPanel();
    javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
    statusMessageLabel = new javax.swing.JLabel();
    statusAnimationLabel = new javax.swing.JLabel();
    progressBar = new javax.swing.JProgressBar();

    mainPanel.setName("mainPanel"); // NOI18N

    jPanel1.setName("jPanel1"); // NOI18N

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 380, Short.MAX_VALUE)
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 229, Short.MAX_VALUE)
    );

    javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
    mainPanel.setLayout(mainPanelLayout);
    mainPanelLayout.setHorizontalGroup(
        mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(mainPanelLayout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap())
    );
    mainPanelLayout.setVerticalGroup(
        mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(mainPanelLayout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap())
    );

    menuBar.setName("menuBar"); // NOI18N

    org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(graphics.GraphicsApp.class).getContext().getResourceMap(GraphicsView.class);
    fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
    fileMenu.setName("fileMenu"); // NOI18N

    javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(graphics.GraphicsApp.class).getContext().getActionMap(GraphicsView.class, this);
    exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
    exitMenuItem.setName("exitMenuItem"); // NOI18N
    fileMenu.add(exitMenuItem);

    menuBar.add(fileMenu);

    helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
    helpMenu.setName("helpMenu"); // NOI18N

    aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
    aboutMenuItem.setName("aboutMenuItem"); // NOI18N
    helpMenu.add(aboutMenuItem);

    menuBar.add(helpMenu);

    statusPanel.setName("statusPanel"); // NOI18N

    statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

    statusMessageLabel.setName("statusMessageLabel"); // NOI18N

    statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
    statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

    progressBar.setName("progressBar"); // NOI18N

    javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
    statusPanel.setLayout(statusPanelLayout);
    statusPanelLayout.setHorizontalGroup(
        statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        .addGroup(statusPanelLayout.createSequentialGroup()
            .addContainerGap()
            .addComponent(statusMessageLabel)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 230, Short.MAX_VALUE)
            .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(statusAnimationLabel)
            .addContainerGap())
    );
    statusPanelLayout.setVerticalGroup(
        statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(statusPanelLayout.createSequentialGroup()
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(statusMessageLabel)
                .addComponent(statusAnimationLabel)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGap(3, 3, 3))
    );

    setComponent(mainPanel);
    setMenuBar(menuBar);
    setStatusBar(statusPanel);
}// </editor-fold>

// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel mainPanel;
private javax.swing.JMenuBar menuBar;
private javax.swing.JProgressBar progressBar;
private javax.swing.JLabel statusAnimationLabel;
private javax.swing.JLabel statusMessageLabel;
private javax.swing.JPanel statusPanel;
// End of variables declaration

private final Timer messageTimer;
private final Timer busyIconTimer;
private final Icon idleIcon;
private final Icon[] busyIcons = new Icon[15];
private int busyIconIndex = 0;

private JDialog aboutBox;
}

Итак, здесь я добавил только

jPanel1.add(new Graph());

Следующим является основной класс:

package graphics;

import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;

/**
* The main class of the application.
*/
public class GraphicsApp extends SingleFrameApplication {

/**
 * At startup create and show the main frame of the application.
 */
@Override protected void startup() {
    show(new GraphicsView(this));
}

/**
 * This method is to initialize the specified window by injecting resources.
 * Windows shown in our application come fully initialized from the GUI
 * builder, so this additional configuration is not needed.
 */
@Override protected void configureWindow(java.awt.Window root) {
}

/**
 * A convenient static getter for the application instance.
 * @return the instance of GraphicsApp
 */
public static GraphicsApp getApplication() {
    return Application.getInstance(GraphicsApp.class);
}

/**
 * Main method launching the application.
 */
public static void main(String[] args) {
    launch(GraphicsApp.class, args);
}
}

На последнем уроке с самой графикой:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
*/

package graphics;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import javax.swing.JPanel;

public class Graph extends JPanel{

int[] data = {
    21, 14, 18, 03, 86, 88, 74, 87, 54, 77,
    61, 55, 48, 60, 49, 36, 38, 27, 20, 18
};
final int PAD = 20;

 protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    int w = getWidth();
    int h = getHeight();
    // Draw ordinate.
    g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD));
    // Draw abcissa.
    g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
    double xInc = (double)(w - 2*PAD)/(data.length-1);
    double scale = (double)(h - 2*PAD)/getMax();
    // Mark data points.
    g2.setPaint(Color.red);
    for(int i = 0; i < data.length; i++) {
        double x = PAD + i*xInc;
        double y = h - PAD - scale*data[i];
        g2.fill(new Ellipse2D.Double(x-2, y-2, 4, 4));
    }
}

private int getMax() {
    int max = -Integer.MAX_VALUE;
    for(int i = 0; i < data.length; i++) {
        if(data[i] > max)
            max = data[i];
    }
    return max;
}
}

У меня есть несколько вопросов:
(a) Как сделать, чтобы график появился в jPanel1?
(b) Чтотакое хорошие практики в инициализации графических компонентов?Я имею в виду, где лучшее место для вызова graph ()?
(c) Для другого приложения я использовал jfreechart для рисования графиков и затем выводил их в файл .jpeg.Могу ли я использовать jfreechart для построения графиков и отображения их непосредственно на странице?

Заранее большое спасибо!

1 Ответ

4 голосов
/ 07 декабря 2010

Некоторые ответы:

(a) Пусть jPanel1 использует BorderLayout для своего менеджера компоновки и добавит график JPanel к jPanel1 в позиции BorderLayout.CENTER.
(b) Мне не ясно, что выспрашиваешь здесь.Вы строите объект тогда, когда вам это нужно.
(c) Да.Графические компоненты JFreeChart расширяют компоненты Swing, я полагаю, JPanel (либо тот, либо JComponent), поэтому вы должны иметь возможность напрямую добавлять их в свой графический интерфейс в качестве компонента, если (и это является ключевым), когда ваш компонент действует как контейнер,это тот, который держит диаграмму, использует правильный менеджер макета.Если вы этого еще не сделали, вам следует прочесть учебник Swing по теме «Компоновка компонентов в контейнере», поскольку эта информация является ключевой для успеха.

Моя последняя рекомендация (на данный момент) - отказаться отгенерация кода NetBeans и создание кода Swing вручную.Это действительно лучший способ изучить Swing.

Удачи!

...