如何创建用于绘图的JPanel [英] How to create a JPanel for graphing
问题描述
我正在制作一个带有4个参数和大小的Panel的函数绘图器,但是我不知道如何创建一个Panel
类,该类将从Grapher
类中提取信息.可以帮忙吗?(参数并不重要,我只想学习如何制作图形面板以备后用)
I'm making a function grapher that take 4 parameters and size for the Panel, but I don't know how to create a Panel
class that will draw the information from the Grapher
class. Can some one help please?(The parameters are not important, I just want to learn how to make a Graph Panel for later use)
import java.awt.BorderLayout;
public class Panel extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
}
/**
* Create the frame.
*/
public Panel(int w, int h) {
setVisible(true);
setSize(w,h);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, w, h);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setBackground(Color.WHITE);
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.setBorder(new EmptyBorder(0, 0, 0, 0));
panel.setBounds(0, 0, w, h);
contentPane.add(panel);
}
public void paint(Graphics g) {
super.paint(g);
//g.drawLine(110, 112,129, 132);
}
public Graphics getGraphics(Graphics g){
return g;
}
}
绘图仪类
import java.awt.EventQueue;
public class Grapher {
private int panelWidth;
private int panelHeight;
int x1;
int x2;
int y1;
int y2;
int a;
int b;
int c;
int d;
private JFrame frmChinhsFunctionGrapher;
private JTextField textFieldXMin;
private JTextField textFieldXMax;
private JTextField textFieldYMin;
private JTextField textFieldYMax;
private JTextField textFieldA;
private JTextField textFieldB;
private JTextField textFieldC;
private JTextField textFieldD;
private JLabel lblPeriod;
private JLabel lblYIntercept;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Grapher window = new Grapher();
window.frmChinhsFunctionGrapher.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Grapher() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmChinhsFunctionGrapher = new JFrame();
frmChinhsFunctionGrapher.setTitle("Chinh's function grapher\r\n");
frmChinhsFunctionGrapher.setBounds(100, 100, 450, 300);
frmChinhsFunctionGrapher.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmChinhsFunctionGrapher.getContentPane().setLayout(null);
textFieldXMin = new JTextField();
textFieldXMin.setText("-200");
textFieldXMin.setBounds(66, 8, 86, 20);
frmChinhsFunctionGrapher.getContentPane().add(textFieldXMin);
textFieldXMin.setColumns(10);
JLabel lblXMin = new JLabel("X min");
lblXMin.setBounds(10, 11, 46, 14);
frmChinhsFunctionGrapher.getContentPane().add(lblXMin);
JLabel lblXMax = new JLabel("X max");
lblXMax.setBounds(10, 42, 46, 14);
frmChinhsFunctionGrapher.getContentPane().add(lblXMax);
textFieldXMax = new JTextField();
textFieldXMax.setText("200");
textFieldXMax.setBounds(66, 39, 86, 20);
frmChinhsFunctionGrapher.getContentPane().add(textFieldXMax);
textFieldXMax.setColumns(10);
textFieldYMin = new JTextField();
textFieldYMin.setText("-200");
textFieldYMin.setBounds(66, 70, 86, 20);
frmChinhsFunctionGrapher.getContentPane().add(textFieldYMin);
textFieldYMin.setColumns(10);
textFieldYMax = new JTextField();
textFieldYMax.setText("200");
textFieldYMax.setBounds(66, 101, 86, 20);
frmChinhsFunctionGrapher.getContentPane().add(textFieldYMax);
textFieldYMax.setColumns(10);
JLabel lblYMin = new JLabel("Y min");
lblYMin.setBounds(10, 73, 46, 14);
frmChinhsFunctionGrapher.getContentPane().add(lblYMin);
JLabel lblYMax = new JLabel("Y max");
lblYMax.setBounds(10, 104, 46, 14);
frmChinhsFunctionGrapher.getContentPane().add(lblYMax);
JLabel lblParameters = new JLabel("Parameters");
lblParameters.setBounds(320, 11, 93, 14);
frmChinhsFunctionGrapher.getContentPane().add(lblParameters);
textFieldA = new JTextField();
textFieldA.setText("100");
textFieldA.setBounds(360, 39, 64, 20);
frmChinhsFunctionGrapher.getContentPane().add(textFieldA);
textFieldA.setColumns(10);
JLabel lblNewLabel = new JLabel("Graph's Height");
lblNewLabel.setBounds(263, 42, 72, 14);
frmChinhsFunctionGrapher.getContentPane().add(lblNewLabel);
textFieldB = new JTextField();
textFieldB.setText("10");
textFieldB.setBounds(360, 70, 64, 20);
frmChinhsFunctionGrapher.getContentPane().add(textFieldB);
textFieldB.setColumns(10);
textFieldC = new JTextField();
textFieldC.setText("100");
textFieldC.setBounds(360, 101, 64, 20);
frmChinhsFunctionGrapher.getContentPane().add(textFieldC);
textFieldC.setColumns(10);
textFieldD = new JTextField();
textFieldD.setText("1");
textFieldD.setBounds(360, 132, 64, 20);
frmChinhsFunctionGrapher.getContentPane().add(textFieldD);
textFieldD.setColumns(10);
JButton btnGraph = new JButton("Graph");
btnGraph.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
getInput();
Panel pn = new Panel(panelWidth, panelHeight);
Graphics gs = pn.getGraphics();
gs.drawLine(100, 100, 200, 200);
}
});
btnGraph.setBounds(10, 228, 89, 23);
frmChinhsFunctionGrapher.getContentPane().add(btnGraph);
lblPeriod = new JLabel("Period");
lblPeriod.setBounds(263, 73, 46, 14);
frmChinhsFunctionGrapher.getContentPane().add(lblPeriod);
lblYIntercept = new JLabel("Vertical shift");
lblYIntercept.setBounds(263, 104, 72, 14);
frmChinhsFunctionGrapher.getContentPane().add(lblYIntercept);
JLabel lblHorizontalShift = new JLabel("Horizontal shift");
lblHorizontalShift.setBounds(263, 135, 86, 14);
frmChinhsFunctionGrapher.getContentPane().add(lblHorizontalShift);
}
public void getInput(){
x1 = Integer.parseInt(textFieldXMin.getText());
x2 = Integer.parseInt(textFieldXMax.getText());
y1 = Integer.parseInt(textFieldYMin.getText());
y2 = Integer.parseInt(textFieldYMax.getText());
a = Integer.parseInt(textFieldA.getText());
b = Integer.parseInt(textFieldB.getText());
c = Integer.parseInt(textFieldC.getText());
d = Integer.parseInt(textFieldD.getText());
panelWidth = Math.abs(x2 - x1);
panelHeight = Math.abs(y2 - y1);
}
}
推荐答案
您的代码存在很多问题
您不应使用null
布局.您不应该扩展JFrame
,即使这样做,也不应覆盖JFrame的paint
方法.您应该在事件调度线程上创建GUI.您应该对如何定义函数的哪个区域到面板的哪个区域有所了解. (绘制sin(x)
之类的函数将得到一条水平的直线,因为这些值将在-1和1之间交替,因此跨度仅为3个像素...)
You should not use the null
layout. You should not extent JFrame
and even if you do it, you should not override the paint
method of JFrame. You should create the GUI on the Event Dispatch Thread. You should have an idea of how you are going to define which area of the function is plotted into which area of the panel. (Plotting a function like sin(x)
will result in a straight, horizontal line, because the values will alternate between -1 and 1, and thus, span a range of only 3 pixels...)
但是,一旦我创建了 https://stackoverflow.com/help/mcve 并显示了非常 em>简单绘图仪,可用于绘制任意函数.也许您会发现其中的一部分鼓舞人心".
However, once I created a https://stackoverflow.com/help/mcve showing a very simple plotter that can be used to plot arbitrary functions. Maybe you find parts of it "inspiring".
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* Main class of the simple function plotter. Contains the
* main method and creates the GUI
*/
public class SimplePlotMain
{
/**
* Entry point
*
* @param args not used
*/
public static void main(String[] args)
{
// Create the GUI on the Event-Dispatch-Thread
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
/**
* Creates the frame containing the simple plotter
*/
private static void createAndShowGUI()
{
// Create the main frame
JFrame frame = new JFrame("SimplePlot");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
frame.setSize(800,600);
// Create the SimplePlotPanel and add it to the frame
SimplePlotPanel plotPanel = new SimplePlotPanel();
frame.getContentPane().add(plotPanel, BorderLayout.CENTER);
// Create the Function that should be plotted, and assign
// it to the SimplePlotPanel
Function function = new Function()
{
@Override
public double compute(double argument)
{
return Math.sin(argument)*argument;
}
};
plotPanel.setFunction(function);
// Create a simple control panel and add it to the frame
JComponent controlPanel = createControlPanel(plotPanel);
frame.getContentPane().add(controlPanel, BorderLayout.EAST);
// As the last action: Make the frame visible
frame.setVisible(true);
}
/**
* Creates a panel containing some Spinners that allow defining
* the area in which the function should be shown
*
* @param plotPanel The SimplePlotPanel, to which the settings
* will be transferred
* @return The control-panel
*/
private static JComponent createControlPanel(
final SimplePlotPanel plotPanel)
{
JPanel controlPanel = new JPanel(new BorderLayout());
JPanel panel = new JPanel(new GridLayout(0,2));
controlPanel.add(panel, BorderLayout.NORTH);
// Create spinners for the minimum and maximum
// X- and Y-values
final JSpinner minXSpinner = new JSpinner(
new SpinnerNumberModel(-1.0, -1000.0, 1000.0, 0.1));
final JSpinner maxXSpinner = new JSpinner(
new SpinnerNumberModel( 1.0, -1000.0, 1000.0, 0.1));
final JSpinner minYSpinner = new JSpinner(
new SpinnerNumberModel(-1.0, -1000.0, 1000.0, 0.1));
final JSpinner maxYSpinner = new JSpinner(
new SpinnerNumberModel( 1.0, -1000.0, 1000.0, 0.1));
// Add the spinners and some labels to the panel
panel.add(new JLabel("minX"));
panel.add(minXSpinner);
panel.add(new JLabel("maxX"));
panel.add(maxXSpinner);
panel.add(new JLabel("minY"));
panel.add(minYSpinner);
panel.add(new JLabel("maxY"));
panel.add(maxYSpinner);
// Create a ChangeListener that will be added to all spinners,
// and which transfers the settings to the SimplePlotPanel
ChangeListener changeListener = new ChangeListener()
{
@Override
public void stateChanged(ChangeEvent event)
{
double minX = ((Double)minXSpinner.getValue()).doubleValue();
double maxX = ((Double)maxXSpinner.getValue()).doubleValue();
double minY = ((Double)minYSpinner.getValue()).doubleValue();
double maxY = ((Double)maxYSpinner.getValue()).doubleValue();
plotPanel.setRangeX(minX, maxX);
plotPanel.setRangeY(minY, maxY);
}
};
minXSpinner.addChangeListener(changeListener);
maxXSpinner.addChangeListener(changeListener);
minYSpinner.addChangeListener(changeListener);
maxYSpinner.addChangeListener(changeListener);
// Set some default values for the Spinners
minXSpinner.setValue(-10.0);
maxXSpinner.setValue( 10.0);
minYSpinner.setValue(-10.0);
maxYSpinner.setValue( 10.0);
return controlPanel;
}
}
/**
* Interface for a general function that may be plotted with
* the SimplePlotPanel
*/
interface Function
{
/**
* Compute the value of the function for the given argument
*
* @param argument The function argument
* @return The function value
*/
double compute(double argument);
}
/**
* The panel in which the function will be plotted
*/
class SimplePlotPanel extends JPanel
{
private static final long serialVersionUID = -6588061082489436970L;
/**
* The function that will be plotted
*/
private Function function;
/**
* The minimal x value that is shown
*/
private double minX = -1.0f;
/**
* The maximal x value that is shown
*/
private double maxX = 1.0f;
/**
* The minimal y value that is shown
*/
private double minY = -1.0f;
/**
* The maximal y value that is shown
*/
private double maxY = 1.0f;
/**
* Set the Function that should be plotted
*
* @param function The Function that should be plotted
*/
public void setFunction(Function function)
{
this.function = function;
repaint();
}
/**
* Set the x-range that should be plotted
*
* @param minX The minimum x-value
* @param maxX The maximum y-value
*/
public void setRangeX(double minX, double maxX)
{
this.minX = minX;
this.maxX = maxX;
repaint();
}
/**
* Set the y-range that should be plotted
*
* @param minY The minimum y-value
* @param maxY The maximum y-value
*/
public void setRangeY(double minY, double maxY)
{
this.minY = minY;
this.maxY = maxY;
repaint();
}
/**
* Overridden method from JComponent: Paints this panel - that
* is, paints the function into the given graphics object
*/
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
g.setColor(Color.WHITE);
g.fillRect(0,0,getWidth(),getHeight());
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
paintAxes(g);
paintFunction(g);
}
/**
* Converts an x-coordinate of the function into an x-value of this panel
*
* @param x The x-coordinate of the function
* @return The x-coordinate on this panel
*/
private int toScreenX(double x)
{
double relativeX = (x-minX)/(maxX-minX);
int screenX = (int)(getWidth() * relativeX);
return screenX;
}
/**
* Converts an y-coordinate of the function into an y-value of this panel
*
* @param y The y-coordinate of the function
* @return The y-coordinate on this panel
*/
private int toScreenY(double y)
{
double relativeY = (y-minY)/(maxY-minY);
int screenY = getHeight() - 1 - (int)(getHeight() * relativeY);
return screenY;
}
/**
* Converts an x-coordinate on this panel into an x-coordinate
* for the function
*
* @param x The x-coordinate on the panel
* @return The x-coordinate for the function
*/
private double toFunctionX(int x)
{
double relativeX = (double)x/getWidth();
double functionX = minX + relativeX * (maxX - minX);
return functionX;
}
/**
* Paints some coordinate axes into the given Graphics
*
* @param g The graphics
*/
private void paintAxes(Graphics2D g)
{
int x0 = toScreenX(0);
int y0 = toScreenY(0);
g.setColor(Color.BLACK);
g.drawLine(0,y0,getWidth(),y0);
g.drawLine(x0,0,x0,getHeight());
}
/**
* Paints the function into the given Graphics
*
* @param g The graphics
*/
private void paintFunction(Graphics2D g)
{
g.setColor(Color.BLUE);
int previousScreenX = 0;
double previousFunctionX = toFunctionX(previousScreenX);
double previousFunctionY = function.compute(previousFunctionX);
int previousScreenY = toScreenY(previousFunctionY);
for (int screenX=1; screenX<getWidth(); screenX++)
{
double functionX = toFunctionX(screenX);
double functionY = function.compute(functionX);
int screenY = toScreenY(functionY);
g.drawLine(previousScreenX, previousScreenY, screenX, screenY);
previousScreenX = screenX;
previousScreenY = screenY;
}
}
}
这篇关于如何创建用于绘图的JPanel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!