Skip to content

Instantly share code, notes, and snippets.

@nbeloglazov
Created February 25, 2010 19:38
Show Gist options
  • Save nbeloglazov/314954 to your computer and use it in GitHub Desktop.
Save nbeloglazov/314954 to your computer and use it in GitHub Desktop.
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