gpt4 book ai didi

java - 如何创建用于绘图的 JPanel

转载 作者:行者123 更新时间:2023-11-30 07:10:45 24 4
gpt4 key购买 nike

我正在制作一个带有 4 个参数和面板大小的函数绘图器,但我不知道如何创建一个 Panel 类来从 Grapher 中提取信息 类。有人可以帮忙吗?(参数不重要,我只是想学习如何制作一个图形面板以备后用)

面板类

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 个像素的范围...)

但是,一旦我创建了一个 https://stackoverflow.com/help/mcve显示一个非常 可用于绘制任意函数的简单绘图仪。也许您会发现它的某些部分“鼓舞人心”。

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


}

关于java - 如何创建用于绘图的 JPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21868284/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com