import javax.swing.*; import java.util.ArrayList; import java.util.Scanner; import java.awt.Point; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Color; import java.lang.Thread; import javax.swing.JButton; import javax.swing.JTextField; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.Canvas; import javax.swing.JComponent; import java.awt.Dimension; public class TwoOptDisplay implements ActionListener {; Point[] city; ArrayList history = new ArrayList(); JFrame window = new JFrame( "TSP recorder" ); TSPPanel graphPanel; JButton runButton = new JButton("Run"); JButton setButton = new JButton("Number of cities"); JTextField cityField = new JTextField(5); TSP tsp; final int OFFSET = 10; public TwoOptDisplay(int n) { this ( TSP.randomPoints(n, 480, 520), (ArrayList) null ); } public TwoOptDisplay( Point[] city, ArrayList list ) { tsp = new TSP(city); if ( list != null ) { this.history = list; } else { history = tsp.removeCrossings(); } this.city = city; graphPanel = new TSPPanel( city ); window.setLayout ( new FlowLayout() ); window.getContentPane().setBackground( Color.WHITE ); window.setVisible(true); window.setSize( 500, 650 ); window.add( graphPanel ); window.add( runButton ); window.add( setButton ); window.add( cityField ); runButton.addActionListener( this ); setButton.addActionListener( this ); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setVisible(true); } public void actionPerformed(ActionEvent e) { if (e.getSource() == setButton ) { String line = cityField.getText(); if ( line.length() == 0 ) { return; } try { int n = Integer.parseInt( line ); city = TSP.randomPoints(n, 480, 520 ); TSP tsp = new TSP(city); graphPanel.init(city); history = tsp.removeCrossings(); trace(); } catch ( NumberFormatException exception) { return; } } else if ( e.getSource() == runButton ) { trace(); } } void trace() { for (int i = 0; i < history.size(); ++i) { graphPanel.updateTour( history.get(i) ); try { Thread.sleep(100); } catch(InterruptedException exception) {}; } } public static void main( String[] args ) { TSP.main( new String[0] ); } } class TSPPanel extends JPanel { final int OFFSET = 10; Point[] city; int[] tour; int xOffset; int yOffset; Color edgeColor = Color.BLUE; Color cityColor = Color.BLACK; Color textColor = Color.BLACK; Color backgroundColor = Color.WHITE; public TSPPanel( Point[] list) { this.tour = new int[0]; setSize( 500, 540 ); setPreferredSize( new Dimension( 500, 540 ) ); init(list); } void init(Point[] list) { this.city = list; if (city.length == 0 ) { return; } int minx = city[0].x; int miny = city[0].y; int maxx = city[0].x; int maxy = city[0].y; for (int i = 0; i < city.length; ++i) { int x = city[i].x; int y = city[i].y; minx = Math.min(x, minx); miny = Math.min(y, miny); maxx = Math.max(x, maxx); maxy = Math.max(y, maxy); } xOffset = OFFSET - minx; yOffset = OFFSET - miny; } public void updateTour(int[] update) { int n = update.length; tour = new int[n]; for (int i = 0; i < n; ++i) { tour[i] = update[i]; } paintTour( getGraphics() ); } public void paintTour(Graphics g) { reset(g); g.setColor( edgeColor ); for (int i = 0; i < tour.length; ++i ) { Point v1 = city[ tour[i] ]; Point v2 = city[ i < tour.length-1 ? tour[i+1] : tour[0] ]; int v1x = xTranslate(v1.x); int v1y = yTranslate(v1.y); int v2x = xTranslate(v2.x); int v2y = yTranslate(v2.y); g.drawLine( v1x, v1y, v2x, v2y); } g.setColor( cityColor ); for (int i = 0; i < city.length; ++i) { int x = xTranslate(city[i].x); int y = yTranslate(city[i].y); g.fillOval(x - 2, y - 2, 4 , 4); } g.setColor( textColor ); for (int i = 0; i < city.length; ++i) { int x = xTranslate(city[i].x); int y = yTranslate(city[i].y); g.drawString(i + "", x+5, y+5); } } int xTranslate(int x) { return x + xOffset; } int yTranslate(int y) { return y + yOffset; } public void paint(Graphics g) { paintTour(g); } public void reset(Graphics g) { g.setColor( backgroundColor ) ; int w = getWidth(); int h = getHeight(); g.fillRect(0, 0, w, h); } }