package lab5client; import java.net.*; import java.io.IOException; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.util.*; public class Lab5Client { static Silhouette area = new Silhouette(5); static ArrayList MarkList = new ArrayList<>(); static ResourceBundle labels; static Locale currentLocale; public static void main(String[] args) { currentLocale = new Locale("ru", "RU"); labels = ResourceBundle.getBundle("lab5client.LabelsBundle", currentLocale); Form mform = new Form(area); mform.SetVisible(true); } public static boolean Request(Float X, Float Y, Float R) throws IOException { DatagramSocket clientSocket = null; try { clientSocket = new DatagramSocket(); } catch (SocketException e3) { e3.printStackTrace(); } InetAddress IPAddress = null; try { IPAddress = InetAddress.getByName("localhost"); } catch (UnknownHostException e2) { clientSocket.close(); } byte[] Data = new byte[1024]; String dataString = X + ";" + Y + ";" + R; Data = dataString.getBytes(); DatagramPacket sendPacket = new DatagramPacket(Data, Data.length, IPAddress, 1000); try { clientSocket.send(sendPacket); } catch (IOException e1) { clientSocket.close(); } byte[] receiveData = new byte[1024]; DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); try { clientSocket.setSoTimeout(100); } catch (SocketException e2) { e2.printStackTrace(); } try { clientSocket.receive(receivePacket); } catch (IOException e1) { throw new IOException(); } String server_result = new String(receivePacket.getData()); clientSocket.close(); return Boolean.valueOf(server_result.trim()); } } class Form { static JTextArea coord_text = new JTextArea("(-; -)"); JFrame window; public Form(final Silhouette area) { //window = new JFrame("Lab4, v.2043. Zhuravlev, 2120"); window = new JFrame(Lab5Client.labels.getString("label_window")); window.setMinimumSize(new Dimension(625, 250)); window.setPreferredSize(new Dimension(650, 500)); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel param_panel = new JPanel(); //панель с параметрами param_panel.setBackground(Color.lightGray); param_panel.setLayout(new FlowLayout()); final Graph graphic_panel = new Graph(); //панель с графиком graphic_panel.addMouseListener(new mListener()); JPanel main_panel = new JPanel(); //основная панель main_panel.setLayout(new GridLayout(1, 3)); JPanel coord_panel = new JPanel(); //панель с X и Y coord_panel.setLayout(new FlowLayout()); final JButton add_button = new JButton(Lab5Client.labels.getString("label_add")); final JButton clear_button = new JButton(Lab5Client.labels.getString("label_clear")); String[] locale_arg = {"ru_RU", "pt_PT"}; JComboBox locale_box = new JComboBox(locale_arg); ItemListener box_listen = new ItemListener() //листенер для бокса { //@Override public void stateChanged(ChangeEvent e) { } @Override public void itemStateChanged(ItemEvent e) { JComboBox jbox = (JComboBox) e.getSource(); String b_value = jbox.getSelectedItem().toString(); if (b_value.equals("ru_RU")) { Lab5Client.currentLocale = new Locale("ru", "RU"); } else { Lab5Client.currentLocale = new Locale("pt", "PT"); } Lab5Client.labels = ResourceBundle.getBundle("lab5client.LabelsBundle", Lab5Client.currentLocale); window.setTitle(Lab5Client.labels.getString("label_window")); add_button.setText(Lab5Client.labels.getString("label_add")); clear_button.setText(Lab5Client.labels.getString("label_clear")); window.repaint(); } }; locale_box.addItemListener(box_listen); JLabel r_label = new JLabel("R:"); //JSpinner для радиуса JSpinner r_spin = new JSpinner(new SpinnerNumberModel(area.getR(), 1, 20, 1)); ChangeListener spin_listen = new ChangeListener() //листенер для спиннера { @Override public void stateChanged(ChangeEvent e) { JSpinner jspin = (JSpinner) e.getSource(); double r_value = (double) jspin.getValue(); System.out.println(r_value); area.setR((float) r_value); graphic_panel.repaint(); } }; r_spin.addChangeListener(spin_listen); JLabel x_label = new JLabel("X:"); //комбобокс для иксов String[] x_values = {"-3", "-2", "-1", "0", "1", "2", "3"}; final JComboBox x_combox = new JComboBox(x_values); x_combox.setSelectedIndex(3); JLabel y_label = new JLabel("Y:"); //чекбоксы для игриков JCheckBox ChB_1 = new JCheckBox("-3", true); JCheckBox ChB_2 = new JCheckBox("-2"); JCheckBox ChB_3 = new JCheckBox("1"); JCheckBox ChB_4 = new JCheckBox("4"); final ArrayList ChB_list = new ArrayList<>(); final ButtonGroup ChB_group = new ButtonGroup(); ChB_list.add(ChB_1); ChB_list.add(ChB_2); ChB_list.add(ChB_3); ChB_list.add(ChB_4); ChB_group.add(ChB_1); ChB_group.add(ChB_2); ChB_group.add(ChB_3); ChB_group.add(ChB_4); ActionListener add_listen = new ActionListener() //листенер для Add { @Override public void actionPerformed(ActionEvent e) { String y = "0"; for (JCheckBox cb : ChB_list) { if (cb.isSelected()) { y = cb.getText(); break; } } Mark m = new Mark(Integer.parseInt((String) x_combox.getSelectedItem()), Integer.parseInt(y)); Lab5Client.MarkList.add(m); coord_text.setText("(" + (String) x_combox.getSelectedItem() + "; " + y + ")"); graphic_panel.repaint(); } }; add_button.addActionListener(add_listen); ActionListener clear_listen = new ActionListener() //листенер для Clear { @Override public void actionPerformed(ActionEvent e) { Lab5Client.MarkList.clear(); graphic_panel.repaint(); } }; clear_button.addActionListener(clear_listen); JLabel coord_label = new JLabel("(X,Y): "); //лэйблы с координатами добавленной точки param_panel.add(clear_button); //добавление на панели компонентов param_panel.add(r_label); param_panel.add(r_spin); coord_panel.add(x_label); coord_panel.add(x_combox); coord_panel.add(y_label); coord_panel.add(ChB_1); coord_panel.add(ChB_2); coord_panel.add(ChB_3); coord_panel.add(ChB_4); coord_panel.add(add_button); param_panel.add(locale_box); param_panel.add(coord_panel); param_panel.add(coord_label); param_panel.add(coord_text); coord_text.setEditable(false); main_panel.add(param_panel); main_panel.add(graphic_panel); window.add(main_panel); window.pack(); } public void SetVisible(boolean visible) { window.setVisible(visible); } } class mListener implements MouseListener { @Override public void mouseClicked(MouseEvent e) { Graph g = (Graph) e.getSource(); int maxR = 20; float x = e.getX(); float y = e.getY(); float w = g.getWidth(); float h = g.getHeight(); float xD = (x - w / 2) * maxR / (w / 2); float yD = -(y - h / 2) * maxR / (h / 2); Mark m = new Mark(xD, yD); String sx = String.format("%.2f", xD), sy = String.format("%.2f", yD); Form.coord_text.setText("(" + sx + "; " + sy + ")"); Lab5Client.MarkList.add(m); g.repaint(); } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { } } class Graph extends JPanel { Graphics2D graphic; @Override protected void paintComponent(Graphics graph) { graphic = (Graphics2D) graph; //установка фона и сглаживания super.paintComponent(graphic); this.setBackground(Color.yellow.brighter()); graphic.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //улучшение визуализации int w = this.getWidth(); int h = this.getHeight(); int r = (int) Lab5Client.area.getR(); graphic.setColor(Color.green.darker()); //рисовка фигуры int[] xPoints = {w / 2 - r * w / 80, w / 2, w / 2, w / 2 + r * w / 40, w / 2 + r * w / 40}; int[] yPoints = {h / 2, h / 2 - r * h / 80, h / 2 + r * h / 40, h / 2 + r * h / 40, h / 2}; graphic.fillPolygon(xPoints, yPoints, 5); graphic.fillArc(w / 2 - r * w / 80, h / 2 - r * h / 80, r * w / 40 + 5, r * h / 40, 180, 90); graphic.setColor(Color.blue.darker()); graphic.drawLine(w / 2, h - 20, w / 2, 20); //оси координат graphic.drawLine(w / 2, 20, w / 2 - 4, 30); graphic.drawLine(w / 2, 20, w / 2 + 4, 30); graphic.drawLine(20, h / 2, w - 20, h / 2); graphic.drawLine(w - 30, h / 2 - 4, w - 20, h / 2); graphic.drawLine(w - 30, h / 2 + 4, w - 20, h / 2); graphic.drawLine(w / 4, h / 2 - 5, w / 4, h / 2 + 5); //цена деления graphic.drawString("-10", w / 4 - 7, h / 2 + 17); graphic.drawLine(w / 8 * 3, h / 2 - 5, w / 8 * 3, h / 2 + 5); graphic.drawString("-5", w / 8 * 3, h / 2 + 17); graphic.drawLine(w / 8 * 5, h / 2 - 5, w / 8 * 5, h / 2 + 5); graphic.drawString("5", w / 8 * 5, h / 2 + 17); graphic.drawLine(w / 4 * 3, h / 2 - 5, w / 4 * 3, h / 2 + 5); graphic.drawString("10", w / 4 * 3 - 3, h / 2 + 17); graphic.drawLine(w / 2 - 5, h / 4, w / 2 + 5, h / 4); graphic.drawString("10", w / 2 + 7, h / 4 + 5); graphic.drawLine(w / 2 - 5, h / 8 * 3, w / 2 + 5, h / 8 * 3); graphic.drawString("5", w / 2 + 7, h / 8 * 3 + 5); graphic.drawLine(w / 2 - 5, h / 4 * 3, w / 2 + 5, h / 4 * 3); graphic.drawString("-10", w / 2 + 7, h / 4 * 3 + 5); graphic.drawLine(w / 2 - 5, h / 8 * 5, w / 2 + 5, h / 8 * 5); graphic.drawString("-5", w / 2 + 7, h / 8 * 5 + 5); for (Mark m : Lab5Client.MarkList) //Отрисовка точек { this.DrawMark(m); } } public void DrawMark(Mark m) { int w = this.getWidth(); int h = this.getHeight(); float x = (m.x * (w / 2) / 20 + w / 2); float y = (-m.y * (h / 2) / 20 + h / 2); Color clr = Color.lightGray; graphic.fillOval((int) x - 2, (int) y - 2, 4, 4); boolean result = false; boolean ok = true; try { result = Lab5Client.Request(m.x, m.y, Lab5Client.area.getR()); } catch (IOException e) { ok = false; } if (ok) { if (result) { clr = Color.green; if (m.inAr == 1 || m.inAr == 0) { runAnim rA = new runAnim(this.getGraphics(), m, this, Lab5Client.area.getR(), (int) x, (int) y); Thread thr = new Thread(rA); thr.start(); m.setInArea(2); } m.setInArea(2); } else { clr = Color.red; m.setInArea(1); } } graphic.setColor(clr); graphic.fillOval((int) x - 2, (int) y - 2, 4, 4); } } class runAnim implements Runnable { Graph src; Graphics2D g; Mark nMark; float r; int x, y; public runAnim(Graphics gr, Mark nMrk, Graph graph, float R, int x, int y) { g = (Graphics2D) gr; nMark = nMrk; src = graph; this.r = R; this.x = x; this.y = y; } @Override public void run() { int w = src.getWidth(), h = src.getHeight(); int alpha = w / 32; g.setColor(Color.green); g.fillOval(x - alpha / 2, y - alpha / 2, alpha, alpha); while (alpha > 4) { g.setColor(Color.green.darker()); //new Color(255,255,255,100) - попытка прозрачности g.fillOval(x - alpha / 2, y - alpha / 2, alpha, alpha); alpha--; g.setColor(Color.green); g.fillOval(x - alpha / 2, y - alpha / 2, alpha, alpha); try { Thread.sleep(100); } catch (Exception e) { } } src.repaint(); Thread.currentThread().interrupt(); } } class Mark { float x, y; int inAr; public Mark(float x, float y) { this.x = x; this.y = y; inAr = 0; } public void setInArea(int i) { inAr = i; } } class Silhouette { float R; public Silhouette(float r) { this.R = r; } public void setR(float r) { this.R = r; } public float getR() { return R; } public boolean IsHit(Mark m) { if (m.y >= 0 && m.x <= 0 && m.y <= m.x + R / 2 || m.y <= 0 && m.x >= 0 && m.x <= R && m.y >= -R || m.y <= 0 && m.x <= 0 && Math.pow(m.x, 2) + Math.pow(m.y, 2) <= Math.pow(R / 2, 2)) { return true; } else { return false; } } }