adopt MVC pattern and add real time graph interface
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package core.gui;
|
||||
|
||||
import core.algo.Learning;
|
||||
import core.controller.ViewListener;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class LearningInfoPanel extends JPanel {
|
||||
private Learning learning;
|
||||
private JLabel policyLabel;
|
||||
private JLabel discountLabel;
|
||||
private JLabel epsilonLabel;
|
||||
private JSlider epsilonSlider;
|
||||
private JSlider delaySlider;
|
||||
|
||||
public LearningInfoPanel(Learning learning, ViewListener viewListener){
|
||||
this.learning = learning;
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
policyLabel = new JLabel();
|
||||
discountLabel = new JLabel();
|
||||
epsilonLabel = new JLabel();
|
||||
epsilonSlider = new JSlider(0, 100, (int)(learning.getEpsilon() * 100));
|
||||
epsilonSlider.addChangeListener(e -> viewListener.onEpsilonChange(epsilonSlider.getValue() / 100f));
|
||||
add(policyLabel);
|
||||
add(discountLabel);
|
||||
add(epsilonLabel);
|
||||
add(epsilonSlider);
|
||||
refreshLabels();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
public void refreshLabels(){
|
||||
policyLabel.setText("Policy: " + learning.getPolicy().getClass());
|
||||
discountLabel.setText("Discount factor: " + learning.getDiscountFactor());
|
||||
epsilonLabel.setText("Exploration (Epsilon): " + learning.getEpsilon());
|
||||
}
|
||||
|
||||
protected JSlider getEpsilonSlider(){
|
||||
return epsilonSlider;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package core.gui;
|
||||
|
||||
import core.algo.Learning;
|
||||
import core.controller.ViewListener;
|
||||
import core.listener.LearningListener;
|
||||
import lombok.Getter;
|
||||
import org.knowm.xchart.QuickChart;
|
||||
import org.knowm.xchart.XChartPanel;
|
||||
import org.knowm.xchart.XYChart;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class View<A extends Enum> implements LearningListener {
|
||||
private Learning<A> learning;
|
||||
@Getter
|
||||
private XYChart chart;
|
||||
@Getter
|
||||
private LearningInfoPanel learningInfoPanel;
|
||||
@Getter
|
||||
private JFrame mainFrame;
|
||||
private XChartPanel<XYChart> rewardChartPanel;
|
||||
private ViewListener viewListener;
|
||||
private List<Double> rewardHistory;
|
||||
|
||||
public View(Learning<A> learning, ViewListener viewListener){
|
||||
this.learning = learning;
|
||||
this.viewListener = viewListener;
|
||||
rewardHistory = new ArrayList<>();
|
||||
this.initMainFrame();
|
||||
}
|
||||
|
||||
private void initMainFrame(){
|
||||
mainFrame = new JFrame();
|
||||
mainFrame.setPreferredSize(new Dimension(1280, 720));
|
||||
mainFrame.setLayout(new BorderLayout());
|
||||
|
||||
initLearningInfoPanel();
|
||||
initRewardChart();
|
||||
|
||||
mainFrame.add(BorderLayout.WEST, learningInfoPanel);
|
||||
mainFrame.add(BorderLayout.CENTER, rewardChartPanel);
|
||||
|
||||
mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
mainFrame.pack();
|
||||
mainFrame.setVisible(true);
|
||||
}
|
||||
|
||||
private void initLearningInfoPanel(){
|
||||
learningInfoPanel = new LearningInfoPanel(learning, viewListener);
|
||||
}
|
||||
|
||||
private void initRewardChart(){
|
||||
chart =
|
||||
QuickChart.getChart(
|
||||
"Rewards per Episode",
|
||||
"Episode",
|
||||
"Reward",
|
||||
"randomWalk",
|
||||
new double[] {0},
|
||||
new double[] {0});
|
||||
chart.getStyler().setLegendVisible(true);
|
||||
chart.getStyler().setXAxisTicksVisible(true);
|
||||
rewardChartPanel = new XChartPanel<>(chart);
|
||||
rewardChartPanel.setPreferredSize(new Dimension(300,300));
|
||||
}
|
||||
|
||||
public void showState(Visualizable state){
|
||||
new JFrame(){
|
||||
{
|
||||
JComponent stateComponent = state.visualize();
|
||||
setPreferredSize(new Dimension(stateComponent.getWidth(), stateComponent.getHeight()));
|
||||
add(stateComponent);
|
||||
setVisible(true);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void updateRewardGraph(double recentReward){
|
||||
rewardHistory.add(recentReward);
|
||||
chart.updateXYSeries("randomWalk", null, rewardHistory, null);
|
||||
rewardChartPanel.revalidate();
|
||||
rewardChartPanel.repaint();
|
||||
}
|
||||
|
||||
public void updateLearningInfoPanel(){
|
||||
this.learningInfoPanel.refreshLabels();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onEpisodeEnd(double sumOfRewards) {
|
||||
SwingUtilities.invokeLater(()->updateRewardGraph(sumOfRewards));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEpisodeStart() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package core.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public interface Visualizable {
|
||||
JComponent visualize();
|
||||
}
|
||||
Reference in New Issue
Block a user