Created
February 25, 2010 19:38
-
-
Save nbeloglazov/314954 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
import java.io.*; | |
import javax.swing.*; | |
import java.awt.*; | |
import java.awt.event.*; | |
public class Application extends JFrame { | |
private enum AlgoState { | |
BEGIN, MIDDLE, END, NONE; | |
} | |
private Solution sol; | |
private AlgoState state; | |
private JScrollPane pane; | |
private JLabel label; | |
private class TreePanel extends JPanel { | |
private FontMetrics fm; | |
private static final int RADIUS = 7; | |
private static final int GAP = 0; | |
private static final int HEIGHT = 20; | |
private Map<Integer, Integer> leftChildren; | |
private Map<Integer, Integer> rightChildren; | |
private int bottom; | |
@Override | |
public void paint(Graphics g) { | |
if (state == AlgoState.NONE) { | |
return; | |
} | |
if (sol.root == null) { | |
g.drawString("Empty", 10, 10); | |
setPreferredSize(new Dimension(100, 50)); | |
return; | |
} | |
bottom = 0; | |
refreshNodes(); | |
int left = GAP + RADIUS + (2 * RADIUS + GAP) * leftChildren.get(sol.root.getValue()); | |
int top = HEIGHT + RADIUS; | |
fm = g.getFontMetrics(); | |
paintNode(sol.root, left, top, (Graphics2D)g); | |
int kk = GAP + (1 + leftChildren.get(sol.root.getValue()) + | |
rightChildren.get(sol.root.getValue())) * | |
(GAP + 2 * RADIUS); | |
this.setPreferredSize(new Dimension(kk, HEIGHT + bottom * (GAP + 2 * RADIUS))); | |
pane.setViewportView(this); | |
} | |
private void paintNode(Solution.Node node, int x, int y, Graphics2D g) { | |
if (node.getRight() != null) { | |
int rightY = y + HEIGHT + 2 * RADIUS; | |
int rightX = x + (2 * RADIUS + GAP) * (1 + leftChildren.get(node.getRight().getValue())); | |
g.setColor(Color.BLACK); | |
g.drawLine(x, y, rightX, rightY); | |
paintNode(node.getRight(), rightX, rightY, g); | |
} | |
if (node.getLeft() != null) { | |
int leftY = y + HEIGHT + 2 * RADIUS; | |
int leftX = x - (2 * RADIUS + GAP) * (1 + rightChildren.get(node.getLeft().getValue())); | |
g.setColor(Color.BLACK); | |
g.drawLine(x, y, leftX, leftY); | |
paintNode(node.getLeft(), leftX, leftY, g); | |
} | |
Color color = null; | |
switch (state) { | |
case BEGIN: | |
color = Color.WHITE; | |
break; | |
case MIDDLE: | |
if (node.isOk() && node.getValue() == sol.mx) { | |
color = Color.red; | |
} else if (node.isOk()) { | |
color = Color.yellow; | |
} else { | |
color = Color.white; | |
} | |
break; | |
case END: | |
if (node.isOk()) { | |
color = Color.yellow; | |
} else { | |
color = Color.white; | |
} | |
break; | |
} | |
g.setColor(color); | |
int value = node.getValue(); | |
int textWidth = fm.stringWidth(String.valueOf(value)); | |
int actualNodeRadius = Math.max(RADIUS, textWidth / 2 + 5); | |
g.fillOval(x - actualNodeRadius, y - RADIUS, actualNodeRadius * 2, RADIUS * 2); | |
g.setColor(Color.black); | |
g.drawOval(x - actualNodeRadius, y - RADIUS, actualNodeRadius * 2, RADIUS * 2); | |
g.drawString(String.valueOf(value), x - textWidth / 2, y + fm.getAscent() / 2); | |
} | |
private int countNodes(Solution.Node node, int bot) { | |
if (node == null) { | |
return 0; | |
} | |
bottom = Math.max(bottom, bot); | |
leftChildren.put(node.getValue(), countNodes(node.getLeft(), bot + 1)); | |
rightChildren.put(node.getValue(), countNodes(node.getRight(), bot + 1)); | |
return 1 + leftChildren.get(node.getValue()) + rightChildren.get(node.getValue()); | |
} | |
private void refreshNodes() { | |
leftChildren = new HashMap<Integer, Integer>(); | |
rightChildren = new HashMap<Integer, Integer>(); | |
countNodes(sol.root, 1); | |
} | |
} | |
private class MyKeyListener extends KeyAdapter { | |
@Override | |
public void keyPressed(KeyEvent e) { | |
if (e.getKeyCode() == KeyEvent.VK_RIGHT) { | |
next(); | |
} | |
} | |
} | |
private void next() { | |
switch (state) { | |
case BEGIN: | |
state = AlgoState.MIDDLE; | |
sol.calculate(); | |
label.setText("Middle"); | |
break; | |
case MIDDLE: | |
state = AlgoState.END; | |
if (sol.mx != -1) { | |
sol.removeNode(sol.mx); | |
} | |
label.setText("Finished"); | |
break; | |
} | |
Application.this.repaint(); | |
} | |
private Application() { | |
pane = new JScrollPane(new TreePanel()); | |
add(pane, BorderLayout.CENTER); | |
sol = new Solution(); | |
label = new JLabel("None"); | |
add(label, BorderLayout.SOUTH); | |
state = AlgoState.NONE; | |
addKeyListener(new MyKeyListener()); | |
JMenuBar bar = new JMenuBar(); | |
JMenuItem dialog = new JMenuItem(new DialogAction()); | |
dialog.setText("From dialog..."); | |
JMenuItem file = new JMenuItem(new FileAction()); | |
file.setText("From file..."); | |
JMenuItem item = new JMenuItem(new AbstractAction() { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
next(); | |
} | |
}); | |
item.setText("Next step"); | |
JMenu menu = new JMenu("Menu"); | |
menu.add(dialog); | |
menu.add(file); | |
menu.add(item); | |
bar.add(menu); | |
setJMenuBar(bar); | |
// this.pack(); | |
setSize(800, 600); | |
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
} | |
private class DialogAction extends AbstractAction { | |
public void actionPerformed(ActionEvent e) { | |
String s = JOptionPane.showInputDialog("Enter k"); | |
if (s == null) { | |
return; | |
} | |
try { | |
int k = Integer.parseInt(s.trim()); | |
s = JOptionPane.showInputDialog("Enter tree"); | |
if (s == null) { | |
return; | |
} | |
sol.readTree(new Scanner(s), k); | |
state = AlgoState.BEGIN; | |
label.setText("Begin"); | |
} catch (Exception ex) { | |
JOptionPane.showMessageDialog(Application.this, "Error:\n" + ex.getMessage()); | |
state = AlgoState.NONE; | |
} | |
Application.this.repaint(); | |
} | |
} | |
private class FileAction extends AbstractAction { | |
public void actionPerformed(ActionEvent e) { | |
try { | |
JFileChooser chooser = new JFileChooser(new File(".")); | |
if (chooser.showOpenDialog(Application.this) == JFileChooser.APPROVE_OPTION) { | |
Scanner sc = new Scanner(chooser.getSelectedFile()); | |
int k = sc.nextInt(); | |
sol.readTree(sc, k); | |
state = AlgoState.BEGIN; | |
label.setText("Begin"); | |
} | |
} catch (Exception ex) { | |
JOptionPane.showMessageDialog(Application.this, "Error:\n" + ex.getMessage()); | |
state = AlgoState.NONE; | |
} | |
Application.this.repaint(); | |
} | |
} | |
/** | |
* @param args | |
*/ | |
public static void main(String[] args) throws IOException { | |
// TODO Auto-generated method stub | |
java.util.List<Integer> lst= new ArrayList<Integer>(); | |
for (int i = 0; i < 100; i++) { | |
lst.add(i); | |
} | |
Collections.shuffle(lst); | |
PrintWriter pw = new PrintWriter(new FileWriter("out.txt")); | |
for (int tmp : lst) { | |
pw.println(tmp); | |
} | |
pw.close(); | |
new Application().setVisible(true); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment