我正在创建一个函数grapher,它为Panel提供了4个参数和大小,但我不知道如何创建一个Panel
类来从Grapher
类中提取信息。有人可以帮忙吗?(参数不重要,我只是想学习如何制作一个Graph Panel供以后使用)
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);
}
}
答案 0 :(得分:4)
您的代码存在一些问题
您不应使用null
布局。您不应该扩展JFrame
,即使您这样做,也不应该覆盖JFrame的paint
方法。您应该在Event Dispatch Thread上创建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;
}
}
}
答案 1 :(得分:0)
首先,我想说删除面板类中的main()方法。它与回答你的问题毫无关系,但我认为这会引起问题和/或混乱。
你需要做的是 1)在面板类中向Grapher类添加一个引用,以便面板绘制方法可以调用Grapher类 2)将引用设置为指向Grapher类的实例 3)使用Panel paint方法调用Grapher类中的方法来绘制图形。
1)添加参考
public class Panel extends JFrame {
private Grapher myGrapher = null; //add this line
private JPanel contentPane;
2)设置参考
public Panel(Grapher graph, int w, int h) { //change this line
myGrapher = graph; //add this line
setVisible(true);
和
public void actionPerformed(ActionEvent arg0) {
getInput();
Panel pn = new Panel(this, panelWidth, panelHeight); //change this line
//Graphics gs = pn.getGraphics(); //remove this line
//gs.drawLine(100, 100, 200, 200); //remove this line
}
3)调用方法
public void paint(Graphics g) {
super.paint(g);
//g.drawLine(110, 112,129, 132);
if(myGrapher != null) //add this line
{
myGrapher.drawGraph(g); //add this line
}
}
并在Grapher类中添加方法
void drawGraph(Graphics g) {
g.drawLine(100, 100, 200, 200);
//whatever else you need to draw the graph
}
祝你好运!