LW GUI
- gui no longer recreate itself every update - fixed node name - added another net
This commit is contained in:
@@ -3,14 +3,16 @@ package net.berack.upo.ai.problem3;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.FileDialog;
|
import java.awt.FileDialog;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.GroupLayout;
|
import javax.swing.GroupLayout;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JSeparator;
|
import javax.swing.JSeparator;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
|
||||||
import net.berack.upo.ai.MyPanel;
|
import net.berack.upo.ai.MyPanel;
|
||||||
|
|
||||||
@@ -21,8 +23,9 @@ import net.berack.upo.ai.MyPanel;
|
|||||||
public class LikelihoodWeightingGUI extends MyPanel {
|
public class LikelihoodWeightingGUI extends MyPanel {
|
||||||
|
|
||||||
private LikelihoodWeighting lw = null;
|
private LikelihoodWeighting lw = null;
|
||||||
|
private OutcomeChartGUI[] chartGUI = null;
|
||||||
|
|
||||||
private final JPanel scroll = new JPanel();
|
private final JPanel scroll = new JPanel(); // tried using JScrollPane but nothing shows up
|
||||||
private final int totalRuns = 1000;
|
private final int totalRuns = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,6 +64,7 @@ public class LikelihoodWeightingGUI extends MyPanel {
|
|||||||
try {
|
try {
|
||||||
var net = SmileLib.getNetworkFrom(fileName);
|
var net = SmileLib.getNetworkFrom(fileName);
|
||||||
this.lw = new LikelihoodWeighting(net);
|
this.lw = new LikelihoodWeighting(net);
|
||||||
|
this.chartGUI = null;
|
||||||
this.updateLW();
|
this.updateLW();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -72,8 +76,23 @@ public class LikelihoodWeightingGUI extends MyPanel {
|
|||||||
*/
|
*/
|
||||||
private void updateLW() {
|
private void updateLW() {
|
||||||
this.lw.updateNetwork(totalRuns);
|
this.lw.updateNetwork(totalRuns);
|
||||||
|
|
||||||
var nodes = this.lw.getAllNodes();
|
var nodes = this.lw.getAllNodes();
|
||||||
|
|
||||||
|
if(chartGUI == null) buildPanel(nodes);
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
for(var node : nodes) chartGUI[i++].updateValues(node.values, node.evidence);
|
||||||
|
|
||||||
|
this.invalidate();
|
||||||
|
this.validate();
|
||||||
|
this.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crea il pannello da zero usando i nodi passati in input come valori
|
||||||
|
* @param nodes i nodi da mostrare
|
||||||
|
*/
|
||||||
|
private void buildPanel(Collection<NetworkNode> nodes) {
|
||||||
var panel = new JPanel();
|
var panel = new JPanel();
|
||||||
var layout = new GroupLayout(panel);
|
var layout = new GroupLayout(panel);
|
||||||
|
|
||||||
@@ -84,16 +103,31 @@ public class LikelihoodWeightingGUI extends MyPanel {
|
|||||||
var gBarch = layout.createParallelGroup();
|
var gBarch = layout.createParallelGroup();
|
||||||
var vGroup = layout.createSequentialGroup();
|
var vGroup = layout.createSequentialGroup();
|
||||||
|
|
||||||
|
this.chartGUI = new OutcomeChartGUI[nodes.size()];
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
for(var node : nodes) {
|
for(var node : nodes) {
|
||||||
var label = new JLabel(node.name);
|
var net = node.net;
|
||||||
var barch = new OutcomeChartGUI(node, i -> {
|
var handle = node.handle;
|
||||||
if(node.evidence == i) node.net.clearEvidence(node.handle);
|
|
||||||
else node.net.setEvidence(node.handle, i);
|
var label = new JTextArea(node.name);
|
||||||
|
label.setEditable(false);
|
||||||
|
label.setLineWrap(true);
|
||||||
|
label.setWrapStyleWord(true);
|
||||||
|
label.setOpaque(false);
|
||||||
|
label.setBorder(BorderFactory.createEmptyBorder());
|
||||||
|
|
||||||
|
var barch = new OutcomeChartGUI(node.outcomes, e -> {
|
||||||
|
if(net.isEvidence(handle) && net.getEvidence(handle) == e)
|
||||||
|
net.clearEvidence(handle);
|
||||||
|
else net.setEvidence(handle, e);
|
||||||
this.updateLW();
|
this.updateLW();
|
||||||
});
|
});
|
||||||
|
this.chartGUI[i++] = barch;
|
||||||
|
|
||||||
var font = label.getFont();
|
var font = label.getFont();
|
||||||
label.setFont(new Font(font.getName(), font.getStyle(), font.getSize() + 4));
|
font = new Font(font.getName(), Font.BOLD, font.getSize() + 2);
|
||||||
|
label.setFont(font);
|
||||||
|
|
||||||
gLabel.addComponent(label);
|
gLabel.addComponent(label);
|
||||||
gBarch.addComponent(barch);
|
gBarch.addComponent(barch);
|
||||||
@@ -108,13 +142,13 @@ public class LikelihoodWeightingGUI extends MyPanel {
|
|||||||
layout.setVerticalGroup(vGroup);
|
layout.setVerticalGroup(vGroup);
|
||||||
layout.setHorizontalGroup(hGroup);
|
layout.setHorizontalGroup(hGroup);
|
||||||
|
|
||||||
|
var sizes = this.scroll.getPreferredSize();
|
||||||
|
sizes.height = panel.getMinimumSize().height;
|
||||||
|
sizes.width -= 10;
|
||||||
|
panel.setPreferredSize(sizes);
|
||||||
|
|
||||||
this.scroll.removeAll();
|
this.scroll.removeAll();
|
||||||
this.scroll.add(panel);
|
this.scroll.add(panel);
|
||||||
this.repaint();
|
|
||||||
|
|
||||||
this.invalidate();
|
|
||||||
this.validate();
|
|
||||||
this.repaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -124,17 +158,19 @@ public class LikelihoodWeightingGUI extends MyPanel {
|
|||||||
var open = new JMenuItem("Open");
|
var open = new JMenuItem("Open");
|
||||||
open.addActionListener(action -> this.openFile());
|
open.addActionListener(action -> this.openFile());
|
||||||
|
|
||||||
var net1 = new JMenuItem("WetGrass net");
|
var nets = new JMenuItem[3];
|
||||||
net1.addActionListener(action -> this.openFile("lw/WetGrass.xdsl"));
|
nets[0] = new JMenuItem("Alarm net");
|
||||||
|
nets[0].addActionListener(action -> this.openFile("lw/Alarm.xdsl"));
|
||||||
|
|
||||||
var net2 = new JMenuItem("Malaria net");
|
nets[1] = new JMenuItem("WetGrass net");
|
||||||
net2.addActionListener(action -> this.openFile("lw/Malaria.xdsl"));
|
nets[1].addActionListener(action -> this.openFile("lw/WetGrass.xdsl"));
|
||||||
|
|
||||||
|
nets[2] = new JMenuItem("Malaria net");
|
||||||
|
nets[2].addActionListener(action -> this.openFile("lw/Malaria.xdsl"));
|
||||||
|
|
||||||
menu.add(open);
|
menu.add(open);
|
||||||
menu.add(new JSeparator());
|
menu.add(new JSeparator());
|
||||||
menu.add(net1);
|
for(var net : nets) menu.add(net);
|
||||||
menu.add(net2);
|
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class NetworkNode {
|
|||||||
NetworkNode(Network net, int handle, Map<Integer, NetworkNode> nodes) {
|
NetworkNode(Network net, int handle, Map<Integer, NetworkNode> nodes) {
|
||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
this.type = net.getNodeType(handle);
|
this.type = net.getNodeType(handle);
|
||||||
this.name = net.getNodeId(handle);
|
this.name = net.getNodeName(handle);
|
||||||
this.net = net;
|
this.net = net;
|
||||||
|
|
||||||
this.outcomes = net.getOutcomeIds(handle);
|
this.outcomes = net.getOutcomeIds(handle);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
|
|
||||||
@@ -26,39 +27,45 @@ public class OutcomeChartGUI extends JPanel {
|
|||||||
new Color(127,255,0),
|
new Color(127,255,0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private JButton[] outcomes;
|
||||||
|
private Label[] valuesChart;
|
||||||
|
private JLabel[] valuesPercent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crea il JPanel da visualizzare a partire da un NetworkNode appropriamente inizializzato.
|
* Crea il JPanel da visualizzare a partire da un NetworkNode appropriamente inizializzato.
|
||||||
* Quando verrà visualizzato, il nodo avrà il nome degli output e i suoi valori in %
|
* Quando verrà visualizzato, il nodo avrà il nome degli output e i suoi valori in %
|
||||||
* con una barra colorata per indicare la grandezza visivamente.
|
* con una barra colorata per indicare la grandezza visivamente.
|
||||||
*
|
*
|
||||||
* @param node il nodo di cui si vogliono visualizzare gli outcome
|
* @param labels i label degli output del nodo
|
||||||
* @param action una azione da fare nel caso in cui venga premuto su un outcome
|
* @param action una azione da fare nel caso in cui venga premuto su un outcome
|
||||||
*/
|
*/
|
||||||
public OutcomeChartGUI(NetworkNode node, Consumer<Integer> action) {
|
public OutcomeChartGUI(String[] labels, Consumer<Integer> action) {
|
||||||
var labels = node.outcomes;
|
|
||||||
var values = node.values;
|
|
||||||
|
|
||||||
if(labels.length != values.length) throw new IllegalArgumentException("Arrays length myst be equals!");
|
|
||||||
this.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(1, 0, 0, 0), BorderFactory.createLineBorder(Color.GRAY)));
|
|
||||||
|
|
||||||
var layout = new GridLayout(labels.length, 2);
|
var layout = new GridLayout(labels.length, 2);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
|
this.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(1, 0, 0, 0), BorderFactory.createLineBorder(Color.GRAY)));
|
||||||
|
|
||||||
|
this.outcomes = new JButton[labels.length];
|
||||||
|
this.valuesChart = new Label[labels.length];
|
||||||
|
this.valuesPercent = new JLabel[labels.length];
|
||||||
|
|
||||||
for(var i = 0; i < labels.length; i++) {
|
for(var i = 0; i < labels.length; i++) {
|
||||||
var value = values[i] * 100;
|
|
||||||
|
|
||||||
var lName = new JButton(labels[i]);
|
var lName = new JButton(labels[i]);
|
||||||
var lValue = new Label(String.format("% 4.2f%%", value));
|
var lValue = new JLabel();
|
||||||
var barchart = new Label();
|
var barchart = new Label();
|
||||||
var size = barchart.getPreferredSize();
|
|
||||||
|
this.outcomes[i] = lName;
|
||||||
|
this.valuesChart[i] = barchart;
|
||||||
|
this.valuesPercent[i] = lValue;
|
||||||
|
|
||||||
final var index = i;
|
final var index = i;
|
||||||
lName.setContentAreaFilled(false);
|
lName.setContentAreaFilled(false);
|
||||||
lName.setFocusable(false);
|
lName.setFocusable(false);
|
||||||
lName.addActionListener(a -> action.accept(index));
|
if(action == null) lName.setBorder(null);
|
||||||
if(node.evidence == i) lName.setForeground(Color.RED);
|
else lName.addActionListener(a -> action.accept(index));
|
||||||
|
|
||||||
size.width = (int) (value * 1.5);
|
var size = barchart.getPreferredSize();
|
||||||
|
size.width = 100;
|
||||||
|
size.height = 100;
|
||||||
barchart.setPreferredSize(size);
|
barchart.setPreferredSize(size);
|
||||||
barchart.setBackground(COLORS[i % COLORS.length]);
|
barchart.setBackground(COLORS[i % COLORS.length]);
|
||||||
|
|
||||||
@@ -76,4 +83,28 @@ public class OutcomeChartGUI extends JPanel {
|
|||||||
this.add(panel2);
|
this.add(panel2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifica i valori mostrati a schermo cambiando anche la grandezza
|
||||||
|
* della barra indicante il valore
|
||||||
|
* @param values i nuovi valori da mostrare
|
||||||
|
* @param evidence indica l'evidenza del nodo
|
||||||
|
*/
|
||||||
|
public void updateValues(double[] values, int evidence) {
|
||||||
|
if(this.outcomes.length != values.length) throw new IllegalArgumentException("Arrays length myst be equals!");
|
||||||
|
|
||||||
|
for(var i = 0; i < this.outcomes.length; i++) {
|
||||||
|
var value = values[i] * 100;
|
||||||
|
var barchart = this.valuesChart[i];
|
||||||
|
|
||||||
|
var size = barchart.getSize();
|
||||||
|
size.width = (int) (value * 1.5);
|
||||||
|
barchart.setSize(size);
|
||||||
|
barchart.setPreferredSize(size);
|
||||||
|
|
||||||
|
this.valuesPercent[i].setText(String.format("% 4.2f%%", value));
|
||||||
|
if(evidence == i) this.outcomes[i].setForeground(Color.RED);
|
||||||
|
else this.outcomes[i].setForeground(Color.BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
92
src/main/resources/lw/Alarm.xdsl
Normal file
92
src/main/resources/lw/Alarm.xdsl
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- This network was created in GeNIe Academic, which can be used for academic teaching and research purposes only -->
|
||||||
|
<smile version="1.0" id="Network1" numsamples="1000" discsamples="10000">
|
||||||
|
<nodes>
|
||||||
|
<cpt id="Burglary">
|
||||||
|
<state id="true" />
|
||||||
|
<state id="false" />
|
||||||
|
<probabilities>0.001 0.9990000000000001</probabilities>
|
||||||
|
</cpt>
|
||||||
|
<cpt id="Earthquake">
|
||||||
|
<state id="true" />
|
||||||
|
<state id="false" />
|
||||||
|
<probabilities>0.002 0.998</probabilities>
|
||||||
|
</cpt>
|
||||||
|
<cpt id="Alarm">
|
||||||
|
<state id="true" />
|
||||||
|
<state id="false" />
|
||||||
|
<parents>Burglary Earthquake</parents>
|
||||||
|
<probabilities>0.95 0.05000000000000004 0.9399999999999999 0.06000000000000005 0.29 0.71 0.001 0.999</probabilities>
|
||||||
|
</cpt>
|
||||||
|
<cpt id="JohnCall">
|
||||||
|
<state id="true" />
|
||||||
|
<state id="false" />
|
||||||
|
<parents>Alarm</parents>
|
||||||
|
<probabilities>0.9 0.09999999999999998 0.05 0.95</probabilities>
|
||||||
|
</cpt>
|
||||||
|
<cpt id="MaryCall">
|
||||||
|
<state id="true" />
|
||||||
|
<state id="false" />
|
||||||
|
<parents>Alarm</parents>
|
||||||
|
<probabilities>0.7 0.3 0.001 0.999</probabilities>
|
||||||
|
</cpt>
|
||||||
|
<cpt id="Radio">
|
||||||
|
<state id="Yes" />
|
||||||
|
<state id="No" />
|
||||||
|
<parents>Earthquake</parents>
|
||||||
|
<probabilities>0.9 0.09999999999999998 0.01 0.99</probabilities>
|
||||||
|
</cpt>
|
||||||
|
</nodes>
|
||||||
|
<extensions>
|
||||||
|
<genie version="1.0" app="GeNIe 4.1.3402.0 ACADEMIC" name="Network1">
|
||||||
|
<node id="Burglary">
|
||||||
|
<name>Burglary</name>
|
||||||
|
<interior color="e5f6f7" />
|
||||||
|
<outline color="000080" />
|
||||||
|
<font color="000000" name="Arial" size="14" />
|
||||||
|
<position>55 39 141 92</position>
|
||||||
|
<barchart active="true" width="128" height="78" />
|
||||||
|
</node>
|
||||||
|
<node id="Alarm">
|
||||||
|
<name>Alarm</name>
|
||||||
|
<interior color="e5f6f7" />
|
||||||
|
<outline color="000080" />
|
||||||
|
<font color="000000" name="Arial" size="14" />
|
||||||
|
<position>178 176 248 219</position>
|
||||||
|
<barchart active="true" width="128" height="78" />
|
||||||
|
</node>
|
||||||
|
<node id="Earthquake">
|
||||||
|
<name>Earthquake</name>
|
||||||
|
<interior color="e5f6f7" />
|
||||||
|
<outline color="000080" />
|
||||||
|
<font color="000000" name="Arial" size="14" />
|
||||||
|
<position>259 32 368 100</position>
|
||||||
|
<barchart active="true" width="128" height="78" />
|
||||||
|
</node>
|
||||||
|
<node id="JohnCall">
|
||||||
|
<name>JohnCall</name>
|
||||||
|
<interior color="e5f6f7" />
|
||||||
|
<outline color="000080" />
|
||||||
|
<font color="000000" name="Arial" size="14" />
|
||||||
|
<position>46 290 139 345</position>
|
||||||
|
<barchart active="true" width="128" height="78" />
|
||||||
|
</node>
|
||||||
|
<node id="MaryCall">
|
||||||
|
<name>MaryCall</name>
|
||||||
|
<interior color="e5f6f7" />
|
||||||
|
<outline color="000080" />
|
||||||
|
<font color="000000" name="Arial" size="14" />
|
||||||
|
<position>302 286 391 341</position>
|
||||||
|
<barchart active="true" width="128" height="78" />
|
||||||
|
</node>
|
||||||
|
<node id="Radio">
|
||||||
|
<name>Radio</name>
|
||||||
|
<interior color="e5f6f7" />
|
||||||
|
<outline color="000080" />
|
||||||
|
<font color="000000" name="Times New Roman" size="16" />
|
||||||
|
<position>441 176 512 220</position>
|
||||||
|
<barchart active="true" width="128" height="81" />
|
||||||
|
</node>
|
||||||
|
</genie>
|
||||||
|
</extensions>
|
||||||
|
</smile>
|
||||||
Reference in New Issue
Block a user