tools.vitruv.change.testutils.changevisualization.ChangeVisualizationUI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tools.vitruv.change.testutils.changevisualization Show documentation
Show all versions of tools.vitruv.change.testutils.changevisualization Show documentation
Utilities for visualization changes on models
The newest version!
package tools.vitruv.change.testutils.changevisualization;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
import tools.vitruv.change.testutils.changevisualization.common.ModelRepositoryChanges;
import tools.vitruv.change.testutils.changevisualization.persistence.ChangeDataSetPersistenceHelper;
import tools.vitruv.change.testutils.changevisualization.ui.ChangesTab;
import tools.vitruv.change.testutils.changevisualization.ui.CloseableTabComponent;
/**
* The frame in which the change visualization is displayed. Also holds default fonts.
*/
public class ChangeVisualizationUI extends JFrame implements MonitoredRepositoryAddedListener {
private static final long serialVersionUID = 8376935677939982608L;
/**
* Creates a font derived from the default font of the java's look and feel for a given fontKey. If the fontKey is
* unknown, the font is derived from Label.font as fallback. For different possible fontKeys search the web for "java
* default font uimanager". Valid fontSizes and styles are not checked here and may therefore throw Exceptions if
* invalid values are given.
* @param fontKey The key identifying the font
* @param size The font size
* @param style The style (Font.bold and so on)
* @return The derived font
*/
private static Font createFont(String fontKey, float size, int style) {
if (fontKey == null) {
// Fallback is Label.font
fontKey = "Label.font";
}
Font defaultFont = (Font) UIManager.get(fontKey);
if (defaultFont == null) {
// Fallback is Label.font
defaultFont = (Font) UIManager.get("Label.font");
System.err.println(fontKey);
}
return defaultFont.deriveFont(size).deriveFont(style);
};
/**
* Default font used for titled borders
*/
public static final Font DEFAULT_TITLED_BORDER_FONT = createFont("TitledBorder.font", 14, Font.BOLD);
/**
* Default font used for trees (=tree nodes)
*/
public static final Font DEFAULT_TREE_FONT = createFont("Tree.font", 16, Font.PLAIN);
/**
* Default font used for tables
*/
public static final Font DEFAULT_TABLE_FONT = createFont("Table.font", 16, Font.PLAIN);
/**
* Default font used for table headers
*/
public static final Font DEFAULT_TABLE_HEADER_FONT = createFont("TableHeader.font", 14, Font.BOLD);
/**
* Default font used for button
*/
public static final Font DEFAULT_BUTTON_FONT = createFont("Button.font", 16, Font.PLAIN);
/**
* Default font used for labels
*/
public static final Font DEFAULT_LABEL_FONT = createFont("Label.font", 16, Font.PLAIN);
/**
* Default font used for textFields
*/
public static final Font DEFAULT_TEXTFIELD_FONT = createFont("TextField.font", 16, Font.PLAIN);
/**
* Default font used for textAreas
*/
public static final Font DEFAULT_TEXTAREA_FONT = createFont("TextArea.font", 16, Font.PLAIN);
/**
* Default font used for checkBoxes
*/
public static final Font DEFAULT_CHECKBOX_FONT = createFont("CheckBox.font", 16, Font.PLAIN);
/**
* Default font used for tabbed pane (titles)
*/
public static final Font DEFAULT_TABBED_PANE_FONT = createFont("TabbedPane.font", 14, Font.BOLD);
/**
* Default font used for menusd
*/
public static final Font DEFAULT_MENU_FONT = createFont("Menu.font", 16, Font.PLAIN);
/**
* Default font used for menuItems
*/
public static final Font DEFAULT_MENUITEM_FONT = createFont("MenuItem.font", 16, Font.PLAIN);
private final ChangeVisualizationDataModel changeVisualizationDataModel;
private JTabbedPane tabbedPane;
public ChangeVisualizationUI(ChangeVisualizationDataModel changeVisualizationDataModel) {
super("Vitruv Change Visualization");
this.changeVisualizationDataModel = changeVisualizationDataModel;
initializeWindow();
initializeContents();
initializeFileMenu();
setupMonitoringForMonitoredRepositoryChanges(changeVisualizationDataModel);
}
private void initializeContents() {
tabbedPane = new JTabbedPane();
tabbedPane.setFont(ChangeVisualizationUI.DEFAULT_TABBED_PANE_FONT);// used just for the title
setContentPane(tabbedPane);
}
private void initializeWindow() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
int screenWidth = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
int screenHeight = java.awt.Toolkit.getDefaultToolkit().getScreenSize().height;
setSize(Math.min(screenWidth - 30, 1890), Math.min(screenHeight - 60, 1020));
setLocationRelativeTo(null);
}
private void setupMonitoringForMonitoredRepositoryChanges(ChangeVisualizationDataModel changeVisualization) {
changeVisualization.registerMonitoredRepositoryAddedListener(this);
tabbedPane.addContainerListener(new ContainerListener() {
@Override
public void componentAdded(ContainerEvent e) {
}
@Override
public void componentRemoved(ContainerEvent e) {
if (e.getChild() instanceof ChangesTab) {
ChangesTab tab = (ChangesTab) e.getChild();
changeVisualization.removeMonitoredRepository(tab.getTitle());
}
}
});
tabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
for (Component component : tabbedPane.getComponents()) {
if (component instanceof ChangesTab) {
((ChangesTab) component).setEnabled(tabbedPane.getSelectedComponent() == component);
}
}
}
});
}
@Override
public void setVisible(boolean isVisible) {
super.setVisible(isVisible);
if (isVisible) {
setAlwaysOnTop(true);
setAlwaysOnTop(false);
}
}
/**
* Listener for the usual zoom in/out on text elements
*/
private final MouseWheelListener mwl = new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (!(e.getSource() instanceof JTextArea)) {
return;
}
if ((e.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) == 0)
return;
// Strg is pressed
JTextArea area = (JTextArea) e.getSource();
if (e.getWheelRotation() <= -1) {
float newSize = area.getFont().getSize() + 2;
if (newSize > 30)
newSize = 30;
area.setFont(area.getFont().deriveFont(newSize));
} else if (e.getWheelRotation() >= 1) {
float newSize = area.getFont().getSize() - 2;
if (newSize < 5)
newSize = 5;
area.setFont(area.getFont().deriveFont(newSize));
}
}
};
private void initializeFileMenu() {
JMenuItem saveItem = new JMenuItem("Save");
saveItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectAndSaveFile();
}
});
JMenuItem loadItem = new JMenuItem("Load");
loadItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectAndLoadFile();
}
});
saveItem.setFont(DEFAULT_MENUITEM_FONT);
loadItem.setFont(DEFAULT_MENUITEM_FONT);
JMenu fileMenu = new JMenu("File");
fileMenu.setFont(DEFAULT_MENU_FONT);
fileMenu.add(saveItem);
fileMenu.addSeparator();
fileMenu.add(loadItem);
JMenuBar menuBar = new JMenuBar();
menuBar.add(fileMenu);
this.setJMenuBar(menuBar);
}
private void selectAndLoadFile() {
// Separate thread to not block UI thread
new Thread(() -> {
JFileChooser fileChooser = createChangesFileChooser();
fileChooser.showOpenDialog(ChangeVisualizationUI.this);
final File selectedFile = fileChooser.getSelectedFile();
if (selectedFile != null) {
load(selectedFile);
}
}).start();
}
private void load(final File file) {
SwingUtilities.invokeLater(() -> {
try {
changeVisualizationDataModel.loadFromFile(file);
} catch (IOException e) {
JOptionPane.showMessageDialog(ChangeVisualizationUI.this, "Error loading changes : " + e.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
}
});
}
private void selectAndSaveFile() {
// Separate thread to not block UI thread
new Thread(() -> {
JFileChooser fileChooser = createChangesFileChooser();
fileChooser.showSaveDialog(ChangeVisualizationUI.this);
final File selectedFile = fileChooser.getSelectedFile();
if (selectedFile != null) {
save(selectedFile);
}
}).start();
}
private JFileChooser createChangesFileChooser() {
JFileChooser chooser = new JFileChooser();
chooser.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory() || (f.isFile() && f.getName().toLowerCase().endsWith(ChangeDataSetPersistenceHelper.FILE_ENDING));
}
@Override
public String getDescription() {
return ChangeDataSetPersistenceHelper.FILE_DESCRIPTION;
}
});
return chooser;
}
private void save(final File file) {
SwingUtilities.invokeLater(() -> {
try {
changeVisualizationDataModel.saveToFile(file);
} catch (IOException e) {
JOptionPane.showMessageDialog(ChangeVisualizationUI.this, "Error saving changes : " + e.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
}
});
}
/**
* Adds a new tab to this frame
* @param title The tab title
* @param component The tab component
*/
private void addTab(final String title, Component component) {
this.tabbedPane.addTab(title, component);
final CloseableTabComponent closeableTabComponent = new CloseableTabComponent(title);
closeableTabComponent.setFont(ChangeVisualizationUI.DEFAULT_TABBED_PANE_FONT);
// Add a listener to the tabComponent to react on its close button
closeableTabComponent.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int choice = JOptionPane.showConfirmDialog(ChangeVisualizationUI.this, "Close tab " + title, "Close tab",
JOptionPane.YES_NO_CANCEL_OPTION);
if (choice != JOptionPane.YES_OPTION) {
return;
}
for (int index = 0; index < tabbedPane.getTabCount(); index++) {
if (tabbedPane.getTabComponentAt(index) == closeableTabComponent) {
tabbedPane.removeTabAt(index);
return;
}
}
}
});
this.tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, closeableTabComponent);
}
/**
* Show a file together with the change-tabs
* @param file The file to load and show
*/
public void addFile(File file) {
try {
InputStream in = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
int read = 0;
while (read < bytes.length) {
read += in.read(bytes, read, bytes.length - read);
}
in.close();
JTextArea area = new JTextArea();
area.setFont(ChangeVisualizationUI.DEFAULT_TEXTAREA_FONT);
area.setText(new String(bytes));
area.addMouseWheelListener(mwl);
JScrollPane scroller = new JScrollPane(area);
addTab(file.getName(), scroller);
} catch (Exception ex) {
JTextArea area = new JTextArea();
area.setFont(ChangeVisualizationUI.DEFAULT_TEXTAREA_FONT);
area.setText("Could not file :" + file);
area.addMouseWheelListener(mwl);
JScrollPane scroller = new JScrollPane(area);
addTab("File error", scroller);
}
}
@Override
public void addedMonitoredRepository(ModelRepositoryChanges newModelRepositoryChanges) {
String repositoryName = newModelRepositoryChanges.getRepositoryName();
addTab(repositoryName, new ChangesTab(newModelRepositoryChanges, false));
}
@Override
public void addedMonitoredRepositoryFromFile(ModelRepositoryChanges newModelRepositoryChanges) {
String repositoryName = newModelRepositoryChanges.getRepositoryName();
addTab(repositoryName, new ChangesTab(newModelRepositoryChanges, true));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy