/* * Scute * * Homepage: http://hyperdata.org/scute * * License : http://www.apache.org/licenses/LICENSE-2.0 * See also license.txt or http://hyperdata.org/wiki/Scute:License * * Danny Ayers 2011 */ package org.hyperdata.scute.main; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Toolkit; import java.util.Arrays; import java.util.List; import javax.swing.*; import javax.swing.border.EtchedBorder; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.plaf.TabbedPaneUI; import javax.swing.plaf.basic.BasicTabbedPaneUI; import javax.swing.text.Document; import com.nilo.plaf.nimrod.NimRODLookAndFeel; import com.nilo.plaf.nimrod.NimRODTheme; //import org.hdesktop.swingx.JXMultiSplitPane; //import org.hdesktop.swingx.JXTitledPanel; //import org.hdesktop.swingx.MultiSplitLayout; //import org.hdesktop.swingx.MultiSplitLayout.Divider; //import org.hdesktop.swingx.MultiSplitLayout.Leaf; //import org.hdesktop.swingx.MultiSplitLayout.Split; import org.jdesktop.swingx.*; import org.jdesktop.swingx.action.*; import org.jdesktop.swingx.MultiSplitLayout.*; import org.hyperdata.resources.scute.ScuteIcons; import org.hyperdata.scute.autosave.AutoSave; import org.hyperdata.scute.autosave.AutoSaveAction; import org.hyperdata.scute.cards.Card; import org.hyperdata.scute.cards.CardFactory; import org.hyperdata.scute.cards.CardsPanel; import org.hyperdata.scute.cards.TaskPanel; import org.hyperdata.scute.help.HelpUI; import org.hyperdata.scute.rdf.ModelContainer; import org.hyperdata.scute.rdf.Models; import org.hyperdata.scute.source.RdfSourcePanel; import org.hyperdata.scute.source.popup.PopupListener; import org.hyperdata.scute.source.popup.SourcePopupMenu; import org.hyperdata.scute.sparql.panels.SparqlCard; import org.hyperdata.scute.status.StatusAction; import org.hyperdata.scute.status.StatusButton; import org.hyperdata.scute.status.StatusInfoPane; import org.hyperdata.scute.syntax.ScuteEditorKit; import org.hyperdata.scute.system.Log; import org.hyperdata.scute.system.panels.LogPane; import org.hyperdata.scute.toolbars.file.FileUI; import org.hyperdata.scute.toolbars.file.IO; // import org.hyperdata.scute.toolbars.history.HistoryToolbar; import org.hyperdata.scute.toolbars.source.EditorToolbar; import org.hyperdata.scute.tree.NodePanel; import org.hyperdata.scute.tree.RdfTreeCard; import org.hyperdata.scute.tree.RdfTreeNode; import org.hyperdata.scute.validate.RdfXmlValidateAction; import org.hyperdata.scute.validate.TurtleValidateAction; /** * The Class Scute. */ public class Scute extends ModelContainer implements TreeSelectionListener, ScuteIF { /** The Constant READ_ONLY_COLOR. */ public static final Color READ_ONLY_COLOR = (Color) UIManager.getDefaults() .get("Button.background"); /** The Constant READ_WRITE_COLOR. */ public static final Color READ_WRITE_COLOR = (Color) UIManager .getDefaults().get("TextField.background"); /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { // need to add a chooser try { // UIManager.setLookAndFeel( // is ugly on this machine!! // UIManager.getSystemLookAndFeelClassName()); // better than default // UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); NimRODTheme nt = new NimRODTheme( "./Scute.theme"); NimRODLookAndFeel nf = new NimRODLookAndFeel(); nf.setCurrentTheme( nt); UIManager.setLookAndFeel( nf); } catch (Exception exception) { // ignore } String homeDir = ""; for (int i = 0; i < args.length; i++){ if(args[i].equals("--home")){ homeDir = args[i+1]; break; } } Config.init(homeDir); // System.out.println("config="+Config.self.CONFIG_FILENAME); new Scute(); } /** The frame. */ private JFrame frame; /** The node panel. */ private NodePanel nodePanel; /** The normal cursor. */ private Cursor normalCursor; /** The normal tree cursor. */ private Cursor normalTreeCursor; /** The panel. */ private final JPanel panel; /** The rdfxml panel. */ private RdfSourcePanel rdfxmlPanel; /** The turtle panel. */ private RdfSourcePanel turtlePanel; /** The tabs. */ // private final JTabbedPane tabs; /** The tree panel. */ private Card treeCard; /** The graph panel. */ private Card graphCard = null; private Card settingsCard; private CardsPanel cardsPanel; private JTabbedPane cardsPanelTabs; private Card fileExplorerCard; private Card sparqlCard; private Card graphManagerCard; public static ScuteHelp scuteHelp; private AutoSave autoSave; private Card triplesCard; private FileUI fileUI; private HelpUI helpUI; private IO io; private ScratchPad scratchPad; private EditorToolbar editorToolbar; private FocusMonitor focusMonitor; private Leaf leftLeaf; private Leaf centerLeaf; private Leaf rightLeaf; private SplitScreen splitScreen; private Card imageCard; private JPanel toolsPanel; private JPanel statusBar; private JScrollPane scratchPane; private JXMultiSplitPane multiSplitPane; private JMenuBar menuBar; private TabbedPaneUI tabUI; // private HistoryToolbar historyToolbar; /** * Instantiates a new scute. */ public Scute() { frame = new JFrame("Scute"); // FIXME restorePreviousState BROKEN - fix! // TODO restorePreviousState BROKEN - fix! // for bootstrapping/debugging // Config.self.setDefaults(); // Config.self.saveNow(); if (Config.self.getSync()) { // previous run was shut down correctly System.out.println("CLEAN"); Config.self.setSync(false); Config.self.saveNow(); } setModel(Models.workingModel); setModelFilename(Config.WORKING_MODEL_FILENAME); setModelURI(Config.WORKING_MODEL_URI); // Models.workingModel = Models.sampleModel; scuteHelp = new ScuteHelp(); panel = new JPanel(new BorderLayout()); focusMonitor = new FocusMonitor(); autoSave = new AutoSave(); editorToolbar = new EditorToolbar(frame); focusMonitor.setEditorToolbar(editorToolbar); makeCardsPanel(); makeScratchPad(); // TODO SEE TABS org.hyperdata.scute.tabs // CardSetView // CardSetModel cardsPanelTabs = new JTabbedPane(); cardsPanelTabs.addTab("Tab 1", cardsPanel); cardsPanelTabs.addTab("Tab 2", new JPanel()); tabUI = cardsPanelTabs.getUI(); showTabs(false); makeSplitScreen(); // effectively presets autoSave.setWorkingModelContainer(this); autoSave.setWorkingModelContainer(Config.self); autoSave.setCurrentTextContainer(turtlePanel); autoSave.setScratchTextContainer(scratchPad); cardsPanel.addChangeListener(autoSave); io = new IO(this, cardsPanel); fileUI = new FileUI(io); // historyToolbar = new HistoryToolbar(); makeToolsPanel(); helpUI = new HelpUI(io); // FIXME basic Save and Load // Set up autosave // FIXME merge with AutoSave stuff above // TODO tweak makeCardsPanel to support list of cards panels TaskPanel taskPanel = new TaskPanel(cardsPanel); multiSplitPane.add(taskPanel, "left"); /* * FIXME validator, autosave must interrupt/be halted immediately on any * actions only one can run at any given time make singleton? */ makeFrame(); splitScreen.setFullMiddle(); showTools(false); showStatusBar(false); if (Config.self.getSync() == false) { // previous run wasn't shut down // correctly System.out.println("RESTORE"); autoSave.restorePreviousState(this); cardsPanel.addChangeListener(autoSave); } } /** * */ private void makeSplitScreen() { // Split Pane stuff // there's an awful lot of it... leftLeaf = new Leaf("left"); centerLeaf = new Leaf("center"); rightLeaf = new Leaf("right"); List children = Arrays.asList(leftLeaf, new Divider(), centerLeaf, new Divider(), rightLeaf); Split splitModel = new Split(); splitModel.setChildren(children); MultiSplitLayout multiSplitLayout = new MultiSplitLayout(); multiSplitLayout.setLayoutMode(MultiSplitLayout.NO_MIN_SIZE_LAYOUT); multiSplitPane = new JXMultiSplitPane(multiSplitLayout); multiSplitPane.getMultiSplitLayout().setModel(splitModel); multiSplitPane.add(cardsPanelTabs, "center"); multiSplitPane.add(new JXTitledPanel("Scratch Pad", scratchPane), "right"); splitScreen = new SplitScreen(multiSplitPane, leftLeaf, centerLeaf, rightLeaf); panel.add(multiSplitPane, BorderLayout.CENTER); } /** * */ private void makeScratchPad() { scratchPad = new ScratchPad("Text"); scratchPad.setEditorKit(new ScuteEditorKit("SPARQL")); scratchPad.setFilename(Config.SCRATCH_FILENAME); scratchPad.addFocusListener(focusMonitor); scratchPad.loadSoon(); // load saved contents scratchPane = new JScrollPane(scratchPad, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scratchPane.setBorder(BorderFactory .createEtchedBorder(EtchedBorder.RAISED)); } /** * */ private void makeToolsPanel() { toolsPanel = new JPanel(); // contains JToolBars panel.add(toolsPanel, BorderLayout.NORTH); toolsPanel.setLayout(new BoxLayout(toolsPanel, BoxLayout.X_AXIS)); // controlPanel.add(splitButtons.getLeftButton()); more trouble than it was worth toolsPanel.add(fileUI.getToolBar()); // toolsPanel.add(historyToolbar); replaced by tabs toolsPanel.add(editorToolbar); // System.out.println("fileUI.getToolBar()="+fileUI.getToolBar()); // System.out.println("historyToolbar="+historyToolbar); // System.out.println("editorToolbar="+editorToolbar); // controlPanel.add(splitButtons.getRightButton()); more trouble than it was worth } private static final int FRAME_X_INSET = 75; private static final int FRAME_Y_INSET = 20; private static final int IDEAL_WIDTH = 1200; private static final int IDEAL_HEIGHT = 600; private void makeFrame() { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int maxWidth = screenSize.width-2*FRAME_X_INSET; int maxHeight = screenSize.height-2*FRAME_Y_INSET; int width = maxWidth < IDEAL_WIDTH ? maxWidth : IDEAL_WIDTH; int height = maxHeight < IDEAL_HEIGHT ? maxHeight : IDEAL_HEIGHT; frame.setBounds(FRAME_X_INSET, FRAME_Y_INSET, width, height); frame.setIconImage(ScuteIcons.applicationIcon.getImage()); frame.addWindowListener(autoSave); // frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); menuBar = new JMenuBar(); menuBar.add(fileUI.getFileMenu()); menuBar.add(editorToolbar.getMenu()); menuBar.add(helpUI.getHelpMenu()); menuBar.setVisible(false); frame.setJMenuBar(menuBar); frame.setContentPane(panel); // frame.pack(); frame.setVisible(true); } /** * */ private void makeCardsPanel() { cardsPanel = new CardsPanel(); makeImageCard(); makeTurtleCard(); makeRdfXmlCard(); makeTreeCard(); makeGraphCard(); makeTriplesCard(); makeSparqlCard(); makeGraphManagerCard(); makeFileExplorerPanel(); makeLogCard(); makeSystemCard(); cardsPanel.setBorder(BorderFactory .createEtchedBorder(EtchedBorder.RAISED)); cardsPanel.add(editorToolbar, BorderLayout.SOUTH); } /** * */ private void makeImageCard() { imageCard = CardFactory.createCard(Card.IMAGE); ((ImageCard)imageCard).setScute(this); //new ImageCard(this); cardsPanel.addPlain(imageCard, "Image"); } /** * */ private void makeSystemCard() { settingsCard = CardFactory.createCard(Card.SETTINGS); // new SystemCard(); // systemPanel.addUserActivityListener(autoSave); cardsPanel.addScroll(settingsCard, "Settings"); } /** * */ private void makeLogCard() { LogPane log = LogPane.getLogPane(); // JScrollPane logScroll = new JScrollPane(log); // logScroll.setBorder(BorderFactory.createLoweredBevelBorder()); LogPane.println("Ok."); // TitledBorder logBorder = BorderFactory.createTitledBorder("Log"); // logScroll.setBorder(logBorder); // cardsPanel.add(logScroll, "Log"); Card logCard = CardFactory.createCard(Card.DEFAULT); logCard.add(log); cardsPanel.addScroll(logCard, "Log"); } /** * */ private void makeFileExplorerPanel() { fileExplorerCard = CardFactory.createCard(Card.FILE_EXPLORER); // new FileExplorerCard(Config.DATA_DIR); fileExplorerCard.addFocusListener(focusMonitor); cardsPanel.add(fileExplorerCard, "Files"); } /** * */ private void makeGraphManagerCard() { graphManagerCard = CardFactory.createCard(Card.GRAPH_MANAGER); // new GraphManagerCard(); graphManagerCard.addFocusListener(focusMonitor); cardsPanel.add(graphManagerCard, "Graphs"); } /** * */ private void makeSparqlCard() { sparqlCard = CardFactory.createCard(Card.SPARQL); // new SparqlCard(frame, focusMonitor); ((SparqlCard)sparqlCard).setFrame(frame); ((SparqlCard)sparqlCard).addFocusMonitor(focusMonitor); sparqlCard.setTextCard(true); cardsPanel.add(sparqlCard, "SPARQL"); } /** * */ private void makeTriplesCard() { triplesCard = CardFactory.createCard(Card.TRIPLES); //new TriplesCard(Models.workingModel); triplesCard.addFocusListener(focusMonitor); // triplesPanel.addUserActivityListener(autoSave); // TODO create UserActivityListener interface // need change listener??? // TODO ADD SELECTION LISTENER - make shared listener? cardsPanel.add(triplesCard, "Triples"); } /** * */ private void makeTreeCard() { treeCard = CardFactory.createCard(Card.TREE); // new RdfTreeCard(Models.workingModel); treeCard.addUserActivityListener(autoSave); treeCard.addFocusListener(focusMonitor); // need change listener??? cardsPanel.add(treeCard, "Tree"); } private void makeGraphCard() { graphCard = CardFactory.createCard(Card.GRAPH); // new GraphCard(Models.workingModel); graphCard.addUserActivityListener(autoSave); graphCard.addFocusListener(focusMonitor); // need change listener??? cardsPanel.add(graphCard, "Graph"); } /** * */ private void makeRdfXmlCard() { rdfxmlPanel = new RdfSourcePanel("RDF/XML"); rdfxmlPanel.setFilename(Config.RDFXML_TEMP); rdfxmlPanel.addUserActivityListener(autoSave); // rdfxmlPanel.loadModel(Models.workingModel); rdfxmlPanel.load(); rdfxmlPanel.setEditorKit(new ScuteEditorKit("XML")); rdfxmlPanel.addFocusListener(focusMonitor); JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEADING)); // left-aligned statusPanel.setBorder(BorderFactory .createEtchedBorder(EtchedBorder.LOWERED)); // add to save-on-shutdown list autoSave.addSaveable(rdfxmlPanel); // set up autosave button StatusAction autosaveAction = new AutoSaveAction(); StatusButton autosaveButton = new StatusButton(autosaveAction, "Unsaved", "Saving...", "Saved"); statusPanel.add(autosaveButton); // Set up validators Document rdfxmlDocument = rdfxmlPanel.getDocument(); StatusAction rdfxmlAction = new RdfXmlValidateAction(rdfxmlDocument); StatusInfoPane validatorPane = new StatusInfoPane(rdfxmlAction); // Set up validator button StatusButton validatorButton = new StatusButton(rdfxmlAction, "Invalid syntax", "Checking syntax...", "Valid syntax"); statusPanel.add(validatorButton); statusPanel.add(validatorPane); cardsPanel.addChangeListener(rdfxmlPanel); Card rdfxmlCard = CardFactory.createCard(Card.RDFXML); rdfxmlCard.setTextCard(true); rdfxmlCard.setTextContainer(rdfxmlPanel); rdfxmlCard.add(new JScrollPane(rdfxmlPanel), BorderLayout.CENTER); rdfxmlCard.add(statusPanel, BorderLayout.SOUTH); cardsPanel.add(rdfxmlCard, "RDF/XML"); } /** * */ private void makeTurtleCard() { turtlePanel = new RdfSourcePanel("Turtle"); turtlePanel.setFilename(Config.TURTLE_TEMP); turtlePanel.addUserActivityListener(autoSave); turtlePanel.setEditorKit(new ScuteEditorKit("Turtle")); turtlePanel.loadModel(getModel()); turtlePanel.load(); turtlePanel.addFocusListener(focusMonitor); SourcePopupMenu popupMenu = new SourcePopupMenu(turtlePanel); PopupListener popupListener = new PopupListener(popupMenu); turtlePanel.addMouseListener(popupListener); cardsPanel.addChangeListener(turtlePanel); // add to save-on-shutdown list autoSave.addSaveable(turtlePanel); statusBar = new JPanel(new FlowLayout(FlowLayout.LEADING)); // left-aligned statusBar.setBorder(BorderFactory .createEtchedBorder(EtchedBorder.LOWERED)); // set up autosave button StatusAction autosaveAction = new AutoSaveAction(); StatusButton autosaveButton = new StatusButton(autosaveAction, "Unsaved", "Saving...", "Saved"); statusBar.add(autosaveButton); // Set up validators Document turtleDocument = turtlePanel.getDocument(); StatusAction turtleAction = new TurtleValidateAction(turtleDocument); StatusInfoPane validatorPane = new StatusInfoPane(turtleAction); // Set up validator button StatusButton validatorButton = new StatusButton(turtleAction, "Invalid syntax", "Checking syntax...", "Valid syntax"); statusBar.add(validatorButton); statusBar.add(validatorPane); Card turtleCard = CardFactory.createCard(Card.TURTLE); turtleCard.setTextCard(true); turtleCard.setTextContainer(turtlePanel); turtleCard.add(new JScrollPane(turtlePanel), BorderLayout.CENTER); turtleCard.add(statusBar, BorderLayout.SOUTH); cardsPanel.add(turtleCard, "Turtle"); } /* * (non-Javadoc) * * @see * javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event * .TreeSelectionEvent) */ @Override public void valueChanged(TreeSelectionEvent event) { final Object object = ((RdfTreeCard)treeCard).getTree() .getLastSelectedPathComponent(); System.out.println("value changed"); if ((object == null)) { System.out.println("null object"); return; } nodePanel.setRdfTreeNode((RdfTreeNode) object); } public void waitCursor(boolean wait) { if (wait) { normalCursor = frame.getCursor(); normalTreeCursor = treeCard.getCursor(); frame.setCursor(new Cursor(Cursor.WAIT_CURSOR)); treeCard.setCursor(new Cursor(Cursor.WAIT_CURSOR)); } else { frame.setCursor(normalCursor); treeCard.setCursor(normalTreeCursor); frame.setCursor(normalCursor); treeCard.setCursor(normalTreeCursor); } } // is needed? public static void setSystemLookFeel() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception exception) { Log.exception(exception); } } /** * @param selectedView */ public void setSelectedCard(String selectedView) { cardsPanel.setCurrentCard(selectedView); } /** * */ public void setDefaultSplit() { splitScreen.setDefaults(); } /** * @param b */ public void showTools(boolean b) { toolsPanel.setVisible(b); menuBar.setVisible(b); // } /** * @param b */ public void showStatusBar(boolean b) { statusBar.setVisible(b); } /* (non-Javadoc) * @see org.hyperdata.scute.main.ScuteIF#showTabs(boolean) */ @Override public void showTabs(boolean b) { if(b){ cardsPanelTabs.setUI(tabUI); } else { cardsPanelTabs.setUI(new BasicTabbedPaneUI() { @Override protected int calculateTabAreaHeight(int tabPlacement, int horizRunCount, int maxTabHeight) { return 0; } }); // cardsPanelTabs.setUI(new javax.swing.plaf.metal.MetalTabbedPaneUI(){ // protected void paintTabArea(Graphics g,int tabPlacement,int selectedIndex){} // }); } } }