- gui no longer recreate itself every update
- fixed node name
- added another net
This commit is contained in:
2024-01-05 15:51:17 +01:00
parent c2cd4e3fb2
commit a0dd2dce2e
4 changed files with 194 additions and 35 deletions

View File

@@ -3,14 +3,16 @@ package net.berack.upo.ai.problem3;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Font;
import java.util.Collection;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import net.berack.upo.ai.MyPanel;
@@ -21,8 +23,9 @@ import net.berack.upo.ai.MyPanel;
public class LikelihoodWeightingGUI extends MyPanel {
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;
/**
@@ -61,6 +64,7 @@ public class LikelihoodWeightingGUI extends MyPanel {
try {
var net = SmileLib.getNetworkFrom(fileName);
this.lw = new LikelihoodWeighting(net);
this.chartGUI = null;
this.updateLW();
} catch (Exception e) {
e.printStackTrace();
@@ -72,8 +76,23 @@ public class LikelihoodWeightingGUI extends MyPanel {
*/
private void updateLW() {
this.lw.updateNetwork(totalRuns);
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 layout = new GroupLayout(panel);
@@ -84,16 +103,31 @@ public class LikelihoodWeightingGUI extends MyPanel {
var gBarch = layout.createParallelGroup();
var vGroup = layout.createSequentialGroup();
this.chartGUI = new OutcomeChartGUI[nodes.size()];
var i = 0;
for(var node : nodes) {
var label = new JLabel(node.name);
var barch = new OutcomeChartGUI(node, i -> {
if(node.evidence == i) node.net.clearEvidence(node.handle);
else node.net.setEvidence(node.handle, i);
var net = node.net;
var handle = node.handle;
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.chartGUI[i++] = barch;
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);
gBarch.addComponent(barch);
@@ -108,13 +142,13 @@ public class LikelihoodWeightingGUI extends MyPanel {
layout.setVerticalGroup(vGroup);
layout.setHorizontalGroup(hGroup);
var sizes = this.scroll.getPreferredSize();
sizes.height = panel.getMinimumSize().height;
sizes.width -= 10;
panel.setPreferredSize(sizes);
this.scroll.removeAll();
this.scroll.add(panel);
this.repaint();
this.invalidate();
this.validate();
this.repaint();
}
@Override
@@ -124,17 +158,19 @@ public class LikelihoodWeightingGUI extends MyPanel {
var open = new JMenuItem("Open");
open.addActionListener(action -> this.openFile());
var net1 = new JMenuItem("WetGrass net");
net1.addActionListener(action -> this.openFile("lw/WetGrass.xdsl"));
var nets = new JMenuItem[3];
nets[0] = new JMenuItem("Alarm net");
nets[0].addActionListener(action -> this.openFile("lw/Alarm.xdsl"));
var net2 = new JMenuItem("Malaria net");
net2.addActionListener(action -> this.openFile("lw/Malaria.xdsl"));
nets[1] = new JMenuItem("WetGrass net");
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(new JSeparator());
menu.add(net1);
menu.add(net2);
for(var net : nets) menu.add(net);
return menu;
}

View File

@@ -37,7 +37,7 @@ public class NetworkNode {
NetworkNode(Network net, int handle, Map<Integer, NetworkNode> nodes) {
this.handle = handle;
this.type = net.getNodeType(handle);
this.name = net.getNodeId(handle);
this.name = net.getNodeName(handle);
this.net = net;
this.outcomes = net.getOutcomeIds(handle);

View File

@@ -8,6 +8,7 @@ import java.util.function.Consumer;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
@@ -26,39 +27,45 @@ public class OutcomeChartGUI extends JPanel {
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.
* Quando verrà visualizzato, il nodo avrà il nome degli output e i suoi valori in %
* 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
*/
public OutcomeChartGUI(NetworkNode node, 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)));
public OutcomeChartGUI(String[] labels, Consumer<Integer> action) {
var layout = new GridLayout(labels.length, 2);
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++) {
var value = values[i] * 100;
var lName = new JButton(labels[i]);
var lValue = new Label(String.format("% 4.2f%%", value));
var lValue = new JLabel();
var barchart = new Label();
var size = barchart.getPreferredSize();
this.outcomes[i] = lName;
this.valuesChart[i] = barchart;
this.valuesPercent[i] = lValue;
final var index = i;
lName.setContentAreaFilled(false);
lName.setFocusable(false);
lName.addActionListener(a -> action.accept(index));
if(node.evidence == i) lName.setForeground(Color.RED);
if(action == null) lName.setBorder(null);
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.setBackground(COLORS[i % COLORS.length]);
@@ -76,4 +83,28 @@ public class OutcomeChartGUI extends JPanel {
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);
}
}
}

View 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>