import java.util.List; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import java.awt.Polygon; import java.awt.EventQueue; import java.awt.GridLayout; import java.awt.event.*; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.event.*; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.ButtonGroup; import javax.swing.JRadioButton; import javax.swing.JSpinner; import javax.swing.JTextArea; import java.awt.Color; import java.awt.Graphics; import javax.swing.JPanel; public class Lab4 extends JFrame { private Point guiPoint = new Point(0,0); private Plot plot; private JTextArea textArea; private JSpinner spinner; private JRadioButton y0; private JRadioButton y1; private JList list; private boolean busy = false; static class Point { private int x; private int y; public Point(int x, int y) { this.x = x; this.y = y; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } public int getX() { return this.x; } public int getY() { return this.y; } } interface PlotListener { public void plotRefreshed(); public void plotAnimationStarted(); public void plotAnimationFinished(); } static class Contorno { private int r; public boolean containsPoint(Point point) { return ((point.getX() >= 0) && ((point.getY() >= 0) && (point.getY() <= r - point.getX()) || (point.getY() <= 0) && (Math.pow(point.getX(),2) + Math.pow(point.getY(), 2) <= Math.pow(r, 2))) || (point.getX() <= 0) && (point.getY() <= 0) && (point.getX() >= -r) && (point.getY() >= -r)); } public Contorno(int r) { this.r = r; } } static class Plot extends JPanel { public static final Color COLOR_BLACK = new Color(0,0,0); public static final Color COLOR_LIGHTGREEN = new Color(124,252,0); public static final Color COLOR_BROWN = new Color(150,75,0); public static final int POINT_RADIUS = 5; public static Color areaColor = COLOR_BROWN; public static final Color COLOR_WHITE = new Color(255,255,255); private int centerX; private int centerY; private int R = 40; private Contorno contorno; public Plot() { contorno = new Contorno(R); } public int getR() { return R; } public void setR(int R) { this.R = (R > 0 ? R : -R); Contorno newContorno = new Contorno(R); for(Point point : points) { if(!newContorno.containsPoint(point) && contorno.containsPoint(point)) { startAnimation(); break; } } contorno = newContorno; refresh(); } public int getCenterX() { return centerX; } public int getCenterY() { return centerY; } private Set listeners = new HashSet(); public void subscribe(PlotListener listener) { listeners.add(listener); } public void unsubscribe(PlotListener listener) { listeners.remove(listener); } private List points = new ArrayList(); public List getPoints() { return points; } public void addPoint(Point point) { points.add(point); refresh(); } public void startAnimation() { new Thread(new Runnable() { public void run() { try { int R0 = COLOR_BROWN.getRed(); int G0 = COLOR_BROWN.getGreen(); final int B0 = COLOR_BROWN.getBlue(); final int N = 50; int R = R0; int G = G0; int B = B0; for(int i = 0; i < N; i++) { R += (255-R0)/N; G += (255-G0)/N; B += (255-B0)/N; areaColor = new Color(R,G,B); repaint(); Thread.sleep(1000/60); } for(int i = 0; i < N; i++) { R -= (255-R0)/N; G -= (255-G0)/N; B -= (255-B0)/N; areaColor = new Color(R,G,B); repaint(); Thread.sleep(1000/60); } for(PlotListener listener : listeners) listener.plotAnimationFinished(); } catch(InterruptedException e) { e.printStackTrace(); } } }).start(); for(PlotListener listener : listeners) listener.plotAnimationStarted(); } public void refresh() { repaint(); for(PlotListener listener : listeners) listener.plotRefreshed(); } private void paintArea(Graphics g, Color color) { paintCircle(g, color); paintTriangle(g, color); paintRectangle(g, color); } private void paintTriangle(Graphics g, Color color) { g.setColor(color); g.fillPolygon(new Polygon(new int[] {centerX + 0, centerX + 0, centerX + R}, new int[] {centerY - 0, centerY - R, centerY - 0}, 3)); } private void paintCircle(Graphics g, Color color) { g.setColor(color); g.fillArc(centerX + 0 - R, centerY - 0 - R,R<<1,R<<1,0,-90); } private void paintRectangle(Graphics g, Color color) { g.setColor(color); g.fillRect(centerX + (-R), centerY, R, R); } protected void paintComponent(Graphics graphics) { super.paintComponent(graphics); graphics.setColor(COLOR_LIGHTGREEN); graphics.fillRect(0,0,getWidth(),getHeight()); centerX = getWidth() >> 1; centerY = getHeight() >> 1; paintArea(graphics, areaColor); graphics.setColor(COLOR_BLACK); graphics.drawLine(0,centerY,getWidth(),centerY); graphics.drawLine(centerX,0,centerX,getHeight()); for(Point point : points) { graphics.setColor(contorno.containsPoint(point) ? COLOR_WHITE : COLOR_BLACK); graphics.fillOval(centerX + point.getX()-(POINT_RADIUS>>1), centerY - point.getY()-(POINT_RADIUS>>1),POINT_RADIUS,POINT_RADIUS); } } } public void AddList() { int[] xSet = new int[] {0,3,8}; list = new JList(new String[] {"X = 0", "X = 3", "X = 8"}); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectedValue(list.getModel().getElementAt(0), false); list.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { guiPoint.setX(xSet[list.getSelectedIndex()]); plot.refresh(); } }); add(list); } public void AddRadioButtons() { GridLayout yLayout = new GridLayout(0,1); JPanel yPanel = new JPanel(); yPanel.setLayout(yLayout); ButtonGroup yGroup = new ButtonGroup(); y0 = new JRadioButton("Y = 0"); y1 = new JRadioButton("Y = 32"); y0.setSelected(true); ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { if(e.getSource() instanceof JRadioButton) { JRadioButton radioButton = (JRadioButton) e.getSource(); if(radioButton.isSelected()) { if(radioButton == y0) guiPoint.setY(0); else if(radioButton == y1) guiPoint.setY(32); plot.refresh(); } } } }; yGroup.add(y0); y0.addActionListener(actionListener); y1.addActionListener(actionListener); yGroup.add(y1); yPanel.add(y0); yPanel.add(y1); add(yPanel); } public void AddSpinner() { spinner = new JSpinner(); ChangeListener listener = new ChangeListener() { public void stateChanged(ChangeEvent e) { if(e.getSource() instanceof JSpinner) { JSpinner spinner = (JSpinner)e.getSource(); String data = spinner.getValue().toString(); plot.setR(new Integer(data)); } } }; spinner.setValue(40); spinner.addChangeListener(listener); add(spinner); } public void AddTextArea() { textArea = new JTextArea(); plot.subscribe(new PlotListener() { public void plotRefreshed() { StringBuilder builder = new StringBuilder(); for(Point point : plot.getPoints()) builder.append("{" + point.getX() + "," + point.getY() + "}\n"); textArea.setText(builder.toString()); } public void plotAnimationStarted() {} public void plotAnimationFinished() {} }); JScrollPane scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); textArea.setEditable(false); add(scroll); } public void AddPlot() { plot = new Plot(); plot.addPoint(guiPoint); plot.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { plot.addPoint(new Point(e.getX() - plot.getCenterX(), plot.getCenterY() - e.getY())); } @Override public void mouseReleased(MouseEvent e) { } }); add(plot); } public void PrepareFrame() { setLayout(new GridLayout(0,2)); setTitle("Lab4"); setSize(600, 400); setResizable(false); setLocationRelativeTo(null); setDefaultCloseOperation(EXIT_ON_CLOSE); } public Lab4() { AddPlot(); AddList(); AddRadioButtons(); AddSpinner(); AddTextArea(); PrepareFrame(); plot.subscribe(new PlotListener() { public void plotRefreshed() { } public void plotAnimationStarted() { plot.setEnabled(false); list.setEnabled(false); spinner.setEnabled(false); y0.setEnabled(false); y1.setEnabled(false); } public void plotAnimationFinished() { plot.setEnabled(true); list.setEnabled(true); spinner.setEnabled(true); y0.setEnabled(true); y1.setEnabled(true); } }); plot.refresh(); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { Lab4 ex = new Lab4(); ex.setVisible(true); } }); } }