|
Java форум JavaTalks форум программистов
|
|
|
|
| Предыдущая тема :: Следующая тема |
| Автор |
Сообщение |
dissonanz : 26 Новичок
|
Июн 22, 2011 11:41 |
|
|
Здравствуйте!
Написал программу, которая рисует график математических функций.
В этой версии используется HashMap.
| Код: |
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("serial")
public class FunctionPlotter extends JFrame implements ActionListener {
/** Width of the window in pixels. */
private int windowWidth = 798;
/** Height of the window in pixels. */
private int windowHeight = 720;
/** paintArea is used to draw the plot. */
private PaintArea paintArea = new PaintArea();
/** Panel used to hold function buttons. */
private JPanel panelNorth = new JPanel();
/** Steps of the zoom **/
private int zoomSteps = 6;
/** Hash-Map to store the given Functions with there methods. */
private Map<String, PlotFunction> fun = new HashMap<String, PlotFunction>();
/**
* Constructor for the class FunctionPlotter.
*/
public FunctionPlotter() {
/* Setting title */
this.setTitle("FunctionPlotter");
/* Create Panels*/
JPanel panelSouth = new JPanel();
JPanel panelWest = new JPanel();
JPanel panelEast = new JPanel();
/* Add north and south panels */
getContentPane().add(panelNorth, BorderLayout.NORTH);
getContentPane().add(panelSouth, BorderLayout.SOUTH);
/* Building south panel */
panelSouth.setLayout(new BorderLayout());
// add west panel to south panel
panelSouth.add(panelWest, BorderLayout.WEST);
// add east panel to south panel
panelSouth.add(panelEast, BorderLayout.EAST);
/* Create buttons */
JButton buttonZoomIn = new JButton("Zoom in");
JButton buttonZoomOut = new JButton("Zoom out");
JButton buttonQuit = new JButton("Quit");
/* Add buttons to south panel */
// zoom in and zoom out buttons to west panel
panelWest.add(buttonZoomIn);
panelWest.add(buttonZoomOut);
// quit button to east panel
panelEast.add(buttonQuit);
/* Add ActionListener to buttons*/
buttonZoomIn.addActionListener(this);
buttonZoomOut.addActionListener(this);
buttonQuit.addActionListener(this);
/* Paint area */
paintArea.zoom(zoomSteps);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().add(paintArea);
}
/**
* Adds a Function Button and adds an ActionListener to it.
*
* @param pf The plot function to add to the application
*/
public void addFunction(final PlotFunction pf) {
// name the button
JButton buttonFunction = new JButton(pf.buttonName());
// install reaction function
buttonFunction.addActionListener(this);
// and add it to the panel
panelNorth.add(buttonFunction);
// store PlotFunction within methods in Hash-Map
fun.put(pf.buttonName(), pf);
}
/**
* Makes the application visible.
*/
public void showApp() {
// set the viewport size
this.setSize(windowWidth, windowHeight);
// set start location for the window
this.setLocation(220, 0);
// and make the app visible
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent click) {
if (click.getActionCommand().equals("Zoom in")) {
zoomSteps++;
paintArea.zoom(zoomSteps);
} else if (click.getActionCommand().equals("Zoom out")) {
zoomSteps--;
paintArea.zoom(zoomSteps);
} else if (click.getActionCommand().equals("Quit")) {
System.exit(0);
} else {
PlotFunction function = fun.get(click.getActionCommand());
paintArea.setPlotFunction(function);
System.out.println(function);
}
}
}
|
Возможно ли решить эту проблему, не применяя HashMap?
Буду благодарен за поддержку! |
|
|
|
 |
bomba_flanker : 1582 Завсегдатай Откуда: Мск/Ульяновск
|
Июн 22, 2011 11:44 |
|
|
| Цитата: |
| Возможно ли решить эту проблему, не применяя HashMap? |
Так Вы проблему озвучьте! _________________ Google Вам в помощь
 |
|
|
|
 |
dissonanz : 26 Новичок
|
Июн 22, 2011 12:14 |
|
|
Функциональность программы должна оставаться такой же, но не лзя применять функцию HashMap.
Т.е. HashMap у нас для того, чтобы откладывать туда функции. Возможно ли найти другой вариант откладывая их? |
|
|
|
 |
dissonanz : 26 Новичок
|
Июн 23, 2011 8:01 |
|
|
| Другими словами - какая существует альтернатива к HashMap? |
|
|
|
 |
Skipy : 4801 Я тут живу! Откуда: Москва, Россия
|
Июн 23, 2011 8:35 |
|
|
Ассоциативный массив - это ассоциативный массив. И альтернатив у него нет. Что вовсе не означает, что его обязательно использовать. Можно и без него, но тогда придется Ваш код наполовину переписать. _________________ С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других! |
|
|
|
 |
dissonanz : 26 Новичок
|
Июн 23, 2011 9:15 |
|
|
| А если без него, то что именно нужно делать? |
|
|
|
 |
Skipy : 4801 Я тут живу! Откуда: Москва, Россия
|
Июн 23, 2011 10:14 |
|
|
Каждой кнопке - собственный обработчик, выполняющий опредеденную функцию. _________________ С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других! |
|
|
|
 |
dissonanz : 26 Новичок
|
Июн 23, 2011 11:16 |
|
|
Решил проблему через анонимных обработчиков (строка 62 - 80).
Единственная проблема - как переместить последнюю функцию else (строка 145)? Ведь именно она пользуется HashMap.
| Код: |
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("serial")
public class FunctionPlotter extends JFrame implements ActionListener {
/** Width of the window in pixels. */
private int windowWidth = 798;
/** Height of the window in pixels. */
private int windowHeight = 720;
/** paintArea is used to draw the plot. */
private PaintArea paintArea = new PaintArea();
/** Panel used to hold function buttons. */
private JPanel panelNorth = new JPanel();
/** Steps of the zoom. **/
private int zoomSteps = 6;
/** Hash-Map to store the given Functions with there methods. */
private Map<String, PlotFunction> fun = new HashMap<String, PlotFunction>();
/**
* Constructor for the class FunctionPlotter.
*/
public FunctionPlotter() {
// Create Panels
JPanel panelSouth = new JPanel();
JPanel panelWest = new JPanel();
JPanel panelEast = new JPanel();
// Add north and south panels
getContentPane().add(panelNorth, BorderLayout.NORTH);
getContentPane().add(panelSouth, BorderLayout.SOUTH);
// Building south panel
panelSouth.setLayout(new BorderLayout());
// add west panel to south panel
panelSouth.add(panelWest, BorderLayout.WEST);
// add east panel to south panel
panelSouth.add(panelEast, BorderLayout.EAST);
// Create buttons
JButton buttonZoomIn = new JButton("Zoom in");
JButton buttonZoomOut = new JButton("Zoom out");
JButton buttonQuit = new JButton("Quit");
// zoom in and zoom out buttons to west panel
panelWest.add(buttonZoomIn);
panelWest.add(buttonZoomOut);
// quit button to east panel
panelEast.add(buttonQuit);
buttonZoomIn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent click) {
zoomSteps++;
paintArea.zoom(zoomSteps);
}
});
buttonZoomOut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent click) {
zoomSteps--;
paintArea.zoom(zoomSteps);
}
});
buttonQuit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent click) {
System.exit(0);
}
});
// ???
//* Paint area
paintArea.zoom(zoomSteps);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().add(paintArea);
}
/**
* Adds a Function Button and adds an ActionListener to it.
*
* @param pf The plot function to add to the application
*/
public void addFunction(final PlotFunction pf) {
// Name of the button
JButton buttonFunction = new JButton(pf.buttonName());
// Reaction function
buttonFunction.addActionListener(this);
// Adding to panel
panelNorth.add(buttonFunction);
// store PlotFunction Hash-Map
fun.put(pf.buttonName(), pf);
}
/**
* Makes the application visible.
*/
public void showApp() {
// Set the title
this.setTitle("FunctionPlotter");
// Set the viewport size
this.setSize(windowWidth, windowHeight);
// Set start location for the window
this.setLocationRelativeTo(null);
// And make the app visible
this.setVisible(true);
}
/**
* ActionListener interface for event-handling.
* @param click Click-button
*/
@Override
public void actionPerformed(ActionEvent click) {
// if the zoom-in button was clicked, do following
if (click.getActionCommand().equals("Zoom in")) {
zoomSteps++;
paintArea.zoom(zoomSteps);
// if the zoom-out button was clicked, do following
} else if (click.getActionCommand().equals("Zoom out")) {
zoomSteps--;
paintArea.zoom(zoomSteps);
// if the quit button was clicked, do following
} else if (click.getActionCommand().equals("Quit")) {
System.exit(0);
// else
} else { // <-------- Как быть с этим?
PlotFunction function = fun.get(click.getActionCommand());
paintArea.setPlotFunction(function);
System.out.println(function);
}
}
}
|
|
|
|
|
 |
Skipy : 4801 Я тут живу! Откуда: Москва, Россия
|
Июн 23, 2011 12:00 |
|
|
Так это и есть основное - повесить обработчики на все кнопки, которые вызывают приход в эту ветку. _________________ С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других! |
|
|
|
 |
dissonanz : 26 Новичок
|
Июн 23, 2011 12:23 |
|
|
Хм... Я что-то совсем не понимаю. Вы не можете подсказать?
Вот так выглядят клас PaintArea и клас PlotFunction.
| Код: |
import javax.swing.*;
import java.awt.*;
import java.text.DecimalFormat;
@SuppressWarnings("serial")
public class PaintArea extends JLabel {
/** Size of the border in pixels. */
int border = 15;
/** Length of tick in pixels. */
int tickLength;
/** Resolution of the number of increment steps per pixel on x-axis. */
double xResolution;
/** The currently active plot function. */
private PlotFunction pf;
/** Origin on x-axis. */
private int xOrigin = getWidth() / 2;
/** Origin on x-axis. */
private int yOrigin = getHeight() / 2;
/** Axis length in pixels. */
private double axisLengthP;
/** Axis length 2 ^ 0 = 1; expressed in units. */
private double axisLengthU;
/** Zoom factor expressed as 2 ^ zoom. */
private double zoomFactor = 0;
/** Storage for graphics environment. */
private Graphics g;
/**
* Paints the component.
*
* @param g The Graphics environment used for painting.
*/
@Override
public void paintComponent(Graphics g) {
// remember Graphics environment
this.g = g;
// Painting the axes
g.drawLine(getWidth() / 2, border,
getWidth() / 2, getHeight() - border);
g.drawLine(border, getHeight() / 2,
getWidth() - border, getHeight() / 2);
// Painting the ticks
int i = 0;
int j = 0;
int k = 0;
int l = 0;
while (i < (getWidth() - xOrigin)) {
pDrawTickX(i);
i += 64;
}
while (j < (getHeight() - yOrigin)) {
pDrawTickY(j);
j += 64;
}
while (k > (xOrigin - getWidth())) {
pDrawTickX(k);
k -= 64;
}
while (l > (yOrigin - getHeight())) {
pDrawTickY(l);
l -= 64;
}
/* Painting function values */
if (pf != null) {
// Print out the function
g.drawString(pf.description(), border, border);
double x1 = (xOrigin - getWidth()) / zoomFactor;
double y1 = pf.f(x1);
double x = (xOrigin - getWidth()) / zoomFactor;
while (x < (getWidth() - xOrigin) / zoomFactor) {
double x2 = x;
double y2 = pf.f(x2);
pDrawLine(x1 * zoomFactor, y1 * zoomFactor, x2 * zoomFactor,
y2 * zoomFactor);
x1 = x2;
y1 = y2;
x += 1 / zoomFactor;
}
}
// Nullify because g will no longer be valid
this.g = null;
}
/**
* Draws a line in the local coordinate system.
*
* @param x1 The x-value of the first point.
* @param y1 The y-value of the first point.
* @param x2 The x-value of the second point.
* @param y2 The y-value of the second point.
*/
private void pDrawLine(double x1, double y1, double x2, double y2) {
int x1draw = px(x1);
int y1draw = py(y1);
int x2draw = px(x2);
int y2draw = py(y2);
g.drawLine(x1draw, y1draw, x2draw, y2draw);
}
/**
* Draws a tick mark in the local coordinate system.
*
* @param v The x-value of the tick mark.
*/
private void pDrawTickX(double v) {
int xCoordinate = px(v);
int yCoordinate = py(0);
// Draw ticks
g.drawLine(xCoordinate, yCoordinate - 5, xCoordinate, yCoordinate + 5);
// Label the coordinate system with NumberFormat
if (v != 0) {
g.drawString(new DecimalFormat("#.##").format(v / zoomFactor),
xCoordinate - 10, yCoordinate + 20);
}
}
/**
* Draws a tick mark in the local coordinate system.
*
* @param v The y-value of the tick mark.
*/
private void pDrawTickY(double v) {
int xCoordinate = px(0);
int yCoordinate = py(v);
// Draw ticks
g.drawLine(xCoordinate - 5, yCoordinate, xCoordinate + 5, yCoordinate);
// Label the coordinate system with NumberFormat
if (v != 0) {
g.drawString(new DecimalFormat("#.##").format(v / zoomFactor),
xCoordinate + 15, yCoordinate + 4);
}
}
/**
* Projects the coordinates for the x-axis from the local coordinate system
* into the screen coordinates.
*
* Because we will have many references to this method the name
* is chosen to be short: 'px' for projection x-axis.
*
* @param v The value to be converted.
* @return the x-coordinate as screen coordinate
*/
private int px(double v) {
// Origin of the coordinate system + the value to be converted
int coordinate = (int) (getWidth() / 2 + v);
return coordinate;
}
/**
* Projects the coordinates for the y-axis from the local coordinate system
* into the screen coordinates.
*
* Because we will have many references to this method the name
* is chosen to be short: 'py' for projection y-axis.
*
* @param v The value to be converted.
* @return the y-coordinate as screen coordinate.
*/
private int py(double v) {
// Origin of the coordinate system - the value to be converted
int coordinate = (int) (getHeight() / 2 - v);
return coordinate;
}
/**
* Zooms in or out on the graph.
*
* @param steps The number of steps to zoom out (negative)
* or zoom in (positive)
*
*/
public void zoom(int steps) {
// Adjust zoom factor
zoomFactor = Math.pow(2, steps);
// Function has changed, update the Paint Area
this.repaint();
}
/**
* Sets the current function.
*
* @param f The function to be set.
*/
public void setPlotFunction(PlotFunction f) {
// Function has changed, update the Paint Area
this.pf = f;
this.repaint();
}
}
|
| Код: |
abstract class PlotFunction {
public abstract double f(double x);
public abstract String description();
public abstract String buttonName();
}
|
Был бы очень благодарен! |
|
|
|
 |
|
|
|