package bs.bs2d.gui.views;
import bs.bs2d.geom.AreaSet;
import bs.bs2d.gui.BusyStateListener;
import bs.bs2d.gui.plot.AreaSetPlotter;
import bs.bs2d.gui.plot.ColorMap;
import bs.bs2d.gui.plot.PlotPanel;
import java.awt.Color;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
/**
*
* @author Djen
*/
public class InfillAreaView implements BSGUIView{
private static final String NAME = "Infill Areas";
// gui
private final PlotPanel content;
private final InfillAreaViewControls controls;
private final JMenu[] menus;
ButtonGroup legendPosition;
// data
private Shape[] areas;
private AreaSet areaSet;
private AreaSetPlotter asPlot;
BusyStateListener bsl;
public InfillAreaView(){
content = new PlotPanel();
controls = new InfillAreaViewControls(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
float thrsh = controls.getAreaThreshold();
int degree = controls.getFilterDegree();
float[] densities = controls.getDensities();
ColorMap.Style style = asPlot.getColorMap().getStyle();
updateAreaSet(thrsh, degree, densities, style, false);
}
});
menus = buildMenus();
}
private JMenu[] buildMenus(){
JMenu[] ms = new JMenu[1];
JMenu m = new JMenu("View");
JMenu menuLegend = new JMenu("Legend Position");
JRadioButtonMenuItem[] mitLegendPos = new JRadioButtonMenuItem[4];
mitLegendPos[0] = new JRadioButtonMenuItem("Upper Left");
mitLegendPos[1] = new JRadioButtonMenuItem("Upper Right");
mitLegendPos[2] = new JRadioButtonMenuItem("Lower Left");
mitLegendPos[3] = new JRadioButtonMenuItem("Lower Right");
mitLegendPos[0].setSelected(true);
legendPosition = new ButtonGroup();
ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
AbstractButton btn = (AbstractButton)e.getSource();
switch (btn.getText()) {
case "Upper Left":
content.setLegendPosition(PlotPanel.UPPER_LEFT);
break;
case "Upper Right":
content.setLegendPosition(PlotPanel.UPPER_RIGHT);
break;
case "Lower Left":
content.setLegendPosition(PlotPanel.LOWER_LEFT);
break;
case "Lower Right":
content.setLegendPosition(PlotPanel.LOWER_RIGHT);
break;
}
}
};
for (JRadioButtonMenuItem item : mitLegendPos){
item.addActionListener(al);
legendPosition.add(item);
menuLegend.add(item);
}
m.add(menuLegend);
m.addSeparator();
JMenuItem mitResetView = new JMenuItem("Reset View");
mitResetView.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
content.resetView();
}
});
m.add(mitResetView);
ms[0] = m;
return ms;
}
@Override
public JComponent getContent() {
return content;
}
@Override
public JComponent getControls() {
return controls;
}
@Override
public JMenu[] getMenus() {
return menus;
}
@Override
public void init(Object data) {
if(data instanceof Object[]){
Object[] odata = (Object[]) data;
if(odata[0] instanceof Shape[] &&
odata[1] instanceof ColorMap.Style){
areas = (Shape[]) odata[0];
float thrsh = controls.getAreaThreshold();
int degree = controls.getFilterDegree();
ColorMap.Style style = (ColorMap.Style) odata[1];
float[] densities = getDefaultDensities(areas.length);
updateAreaSet(thrsh, degree, densities, style, true);
return;
}
}
// invalid data
areas = null;
asPlot = null;
content.setPlotObject(null, true);
}
private void updateAreaSet(final float thrsh, final int degree,
final float[] densities, final ColorMap.Style style,
final boolean resetView) {
bsl.setBusy(true);
new Thread(new Runnable() {
@Override
public void run() {
areaSet = new AreaSet(areas, thrsh, degree);
asPlot = new AreaSetPlotter(areaSet, densities, style);
content.setPlotObject(asPlot, resetView);
Color[] colors = asPlot.getColorMap().getColors();
controls.init(densities, colors);
bsl.setBusy(false);
}
}).start();
}
private static float[] getDefaultDensities(int res){
float[] densities = new float[res];
for (int i = 0; i < densities.length; i++) {
// float d = (i + 1f) / res;
// densities[i] = (int)(d * 100) / 100f;
densities[i] = 0.8f/(float)Math.pow(2, res-i-1);
}
System.out.println(Arrays.toString(densities));
return densities;
}
@Override
public Object getData() {
return new Object[]{areaSet, controls.getDensities()};
}
@Override
public String getName() {
return NAME;
}
@Override
public void setBusyStateListener(BusyStateListener bsl) {
this.bsl = bsl;
}
}