| | |
| | | /* |
| | | * Copyright 2011-17 Fraunhofer ISE, energy & meteo Systems GmbH and other contributors |
| | | * |
| | | * Licensed under the Apache License, Version 2.0 (the "License"); |
| | | * you may not use this file except in compliance with the License. |
| | | * You may obtain a copy of the License at |
| | | * |
| | | * http://www.apache.org/licenses/LICENSE-2.0 |
| | | * |
| | | * Unless required by applicable law or agreed to in writing, software |
| | | * distributed under the License is distributed on an "AS IS" BASIS, |
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| | | * See the License for the specific language governing permissions and |
| | | * limitations under the License. |
| | | * |
| | | */ |
| | | package org.openmuc.openiec61850.clientgui; |
| | | |
| | | import java.awt.Component; |
| | | import java.awt.Dimension; |
| | | import java.awt.GridBagConstraints; |
| | | import java.awt.GridBagLayout; |
| | | import java.awt.Insets; |
| | | import java.awt.event.ActionEvent; |
| | | import java.awt.event.ActionListener; |
| | | import java.io.FileInputStream; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.net.InetAddress; |
| | | import java.net.UnknownHostException; |
| | | import java.util.Properties; |
| | | |
| | | import javax.swing.Box; |
| | | import javax.swing.BoxLayout; |
| | | import javax.swing.JButton; |
| | | import javax.swing.JFrame; |
| | | import javax.swing.JLabel; |
| | | import javax.swing.JPanel; |
| | | import javax.swing.JScrollPane; |
| | | import javax.swing.JSeparator; |
| | | import javax.swing.JTextField; |
| | | import javax.swing.JTree; |
| | | import javax.swing.ToolTipManager; |
| | | import javax.swing.UIManager; |
| | | import javax.swing.UnsupportedLookAndFeelException; |
| | | import javax.swing.event.TreeSelectionEvent; |
| | | import javax.swing.event.TreeSelectionListener; |
| | | import javax.swing.tree.DefaultMutableTreeNode; |
| | | import javax.swing.tree.DefaultTreeModel; |
| | | |
| | | import org.openmuc.openiec61850.ClientAssociation; |
| | | import org.openmuc.openiec61850.ClientSap; |
| | | import org.openmuc.openiec61850.ServerModel; |
| | | import org.openmuc.openiec61850.ServiceError; |
| | | import org.openmuc.openiec61850.clientgui.util.Counter; |
| | | |
| | | public class ClientGui extends JFrame implements ActionListener, TreeSelectionListener { |
| | | |
| | | private static final String ADDRESS_KEY = "serverAddress"; |
| | | private static final String PORT_KEY = "serverPort"; |
| | | private static final String TSEL_LOCAL_KEY = "tselLocal"; |
| | | private static final String TSEL_REMOTE_KEY = "tselRemote"; |
| | | private static final String LASTCONNECTION_FILE = "lastconnection.properties"; |
| | | |
| | | private static final long serialVersionUID = -1938913902977758367L; |
| | | |
| | | private final JTextField ipTextField = new JTextField("127.0.0.1"); |
| | | private final JTextField portTextField = new JTextField("10002"); |
| | | private final JTree tree = new JTree(new DefaultMutableTreeNode("No server connected")); |
| | | private final JPanel detailsPanel = new JPanel(); |
| | | private final GridBagLayout detailsLayout = new GridBagLayout(); |
| | | |
| | | private final SettingsFrame settingsFrame = new SettingsFrame(); |
| | | |
| | | private ClientAssociation association; |
| | | |
| | | private DataTreeNode selectedNode; |
| | | |
| | | public ClientGui() { |
| | | super("WHYC IEC61850 Client"); |
| | | |
| | | Properties lastConnection = new Properties(); |
| | | |
| | | InputStream in = null; |
| | | try { |
| | | in = new FileInputStream(LASTCONNECTION_FILE); |
| | | lastConnection.load(in); |
| | | |
| | | ipTextField.setText(lastConnection.getProperty(ADDRESS_KEY)); |
| | | portTextField.setText(lastConnection.getProperty(PORT_KEY)); |
| | | |
| | | String[] tselString = lastConnection.getProperty(TSEL_LOCAL_KEY).split(","); |
| | | byte[] tsel = new byte[] { (byte) Integer.parseInt(tselString[0]), (byte) Integer.parseInt(tselString[1]) }; |
| | | settingsFrame.setTselLocal(tsel); |
| | | |
| | | tselString = lastConnection.getProperty(TSEL_REMOTE_KEY).split(","); |
| | | tsel = new byte[] { (byte) Integer.parseInt(tselString[0]), (byte) Integer.parseInt(tselString[1]) }; |
| | | settingsFrame.setTselRemote(tsel); |
| | | } catch (Exception ex) { |
| | | // no lastconnection.properties file found, use default. |
| | | } finally { |
| | | try { |
| | | if (in != null) { |
| | | in.close(); |
| | | } |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | |
| | | } |
| | | } |
| | | |
| | | try { |
| | | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); |
| | | } catch (ClassNotFoundException e) { |
| | | System.out.println("Class not found: " + e.getMessage()); |
| | | } catch (InstantiationException e) { |
| | | System.out.println("Object not instantiated: " + e.getMessage()); |
| | | } catch (IllegalAccessException e) { |
| | | System.out.println("Illegal acces: " + e.getMessage()); |
| | | } catch (UnsupportedLookAndFeelException e) { |
| | | System.out.println("Unsupported LookAndFeel: " + e.getMessage()); |
| | | } |
| | | |
| | | GridBagLayout gbl = new GridBagLayout(); |
| | | setLayout(gbl); |
| | | |
| | | JPanel topPanel = new JPanel(); |
| | | topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS)); |
| | | |
| | | GridBagConstraints topPanelConstraint = new GridBagConstraints(); |
| | | topPanelConstraint.fill = GridBagConstraints.HORIZONTAL; |
| | | topPanelConstraint.gridwidth = GridBagConstraints.REMAINDER; |
| | | topPanelConstraint.gridx = 0; |
| | | topPanelConstraint.gridy = 0; |
| | | topPanelConstraint.insets = new Insets(5, 5, 5, 5); |
| | | topPanelConstraint.anchor = GridBagConstraints.NORTH; |
| | | gbl.setConstraints(topPanel, topPanelConstraint); |
| | | add(topPanel); |
| | | |
| | | JLabel label = new JLabel("IP: "); |
| | | topPanel.add(label); |
| | | topPanel.add(ipTextField); |
| | | topPanel.add(Box.createRigidArea(new Dimension(5, 0))); |
| | | |
| | | label = new JLabel("Port: "); |
| | | topPanel.add(label); |
| | | topPanel.add(portTextField); |
| | | topPanel.add(Box.createRigidArea(new Dimension(5, 0))); |
| | | |
| | | JButton newServerButton = new JButton("Connect to Server"); |
| | | newServerButton.addActionListener(this); |
| | | newServerButton.setActionCommand("Connect"); |
| | | topPanel.add(newServerButton); |
| | | topPanel.add(Box.createRigidArea(new Dimension(5, 0))); |
| | | |
| | | JButton settingsButton = new JButton("Settings"); |
| | | settingsButton.addActionListener(this); |
| | | settingsButton.setActionCommand("Settings"); |
| | | topPanel.add(settingsButton); |
| | | |
| | | ToolTipManager.sharedInstance().registerComponent(tree); |
| | | |
| | | tree.setCellRenderer(new DataObjectTreeCellRenderer()); |
| | | tree.setMinimumSize(new Dimension(100, 0)); |
| | | tree.addTreeSelectionListener(this); |
| | | JScrollPane treeScrollPane = new JScrollPane(tree); |
| | | treeScrollPane.setMinimumSize(new Dimension(100, 0)); |
| | | treeScrollPane.setVisible(true); |
| | | |
| | | GridBagConstraints treeScrollPaneConstraint = new GridBagConstraints(); |
| | | treeScrollPaneConstraint.fill = GridBagConstraints.BOTH; |
| | | treeScrollPaneConstraint.gridx = 0; |
| | | treeScrollPaneConstraint.gridy = 1; |
| | | treeScrollPaneConstraint.weightx = 0.2; |
| | | treeScrollPaneConstraint.weighty = 1; |
| | | treeScrollPaneConstraint.insets = new Insets(5, 5, 5, 5); |
| | | gbl.setConstraints(treeScrollPane, treeScrollPaneConstraint); |
| | | add(treeScrollPane); |
| | | |
| | | detailsPanel.setLayout(detailsLayout); |
| | | detailsPanel.setAlignmentY(TOP_ALIGNMENT); |
| | | JScrollPane detailsScrollPane = new JScrollPane(detailsPanel); |
| | | detailsPanel.setMaximumSize(detailsScrollPane.getSize()); |
| | | detailsScrollPane.setMinimumSize(new Dimension(0, 0)); |
| | | detailsScrollPane.setPreferredSize(new Dimension(200, 0)); |
| | | detailsScrollPane.setVisible(true); |
| | | GridBagConstraints detailsScrollPaneConstraint = new GridBagConstraints(); |
| | | detailsScrollPaneConstraint.fill = GridBagConstraints.BOTH; |
| | | detailsScrollPaneConstraint.gridx = 1; |
| | | detailsScrollPaneConstraint.gridy = 1; |
| | | detailsScrollPaneConstraint.weightx = 0.8; |
| | | detailsScrollPaneConstraint.weighty = 1; |
| | | detailsScrollPaneConstraint.insets = new Insets(5, 5, 5, 5); |
| | | gbl.setConstraints(detailsScrollPane, detailsScrollPaneConstraint); |
| | | add(detailsScrollPane); |
| | | |
| | | // Display the window. |
| | | setSize(700, 500); |
| | | setMinimumSize(new Dimension(420, 0)); |
| | | setVisible(true); |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | ClientGui clientGui = new ClientGui(); |
| | | clientGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
| | | clientGui.setVisible(true); |
| | | } |
| | | |
| | | @Override |
| | | public void actionPerformed(ActionEvent arg0) { |
| | | if ("connect".equalsIgnoreCase(arg0.getActionCommand())) { |
| | | connect(); |
| | | } |
| | | else if ("reload".equalsIgnoreCase(arg0.getActionCommand())) { |
| | | reload(); |
| | | } |
| | | else if ("write".equalsIgnoreCase(arg0.getActionCommand())) { |
| | | write(); |
| | | } |
| | | else if ("settings".equalsIgnoreCase(arg0.getActionCommand())) { |
| | | settingsFrame.setVisible(true); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void valueChanged(TreeSelectionEvent e) { |
| | | detailsPanel.removeAll(); |
| | | detailsPanel.repaint(); |
| | | if (e.getNewLeadSelectionPath() != null) { |
| | | selectedNode = (DataTreeNode) e.getNewLeadSelectionPath().getLastPathComponent(); |
| | | if (selectedNode.readable()) { |
| | | showDataDetails(selectedNode, new Counter()); |
| | | |
| | | JPanel filler = new JPanel(); |
| | | GridBagConstraints gbc = new GridBagConstraints(); |
| | | gbc.fill = GridBagConstraints.BOTH; |
| | | gbc.gridx = 0; |
| | | gbc.gridy = GridBagConstraints.RELATIVE; |
| | | gbc.gridwidth = 3; |
| | | gbc.gridheight = 1; |
| | | gbc.weightx = 0; |
| | | gbc.weighty = 1; |
| | | detailsLayout.setConstraints(filler, gbc); |
| | | detailsPanel.add(filler); |
| | | |
| | | JButton button = new JButton("Reload values"); |
| | | button.addActionListener(this); |
| | | button.setActionCommand("reload"); |
| | | gbc = new GridBagConstraints(); |
| | | gbc.fill = GridBagConstraints.NONE; |
| | | gbc.gridx = 0; |
| | | gbc.gridy = GridBagConstraints.RELATIVE; |
| | | gbc.gridwidth = 2; |
| | | gbc.gridheight = 1; |
| | | gbc.weightx = 0; |
| | | gbc.weighty = 0; |
| | | gbc.anchor = GridBagConstraints.SOUTHWEST; |
| | | gbc.insets = new Insets(0, 5, 5, 0); |
| | | detailsLayout.setConstraints(button, gbc); |
| | | detailsPanel.add(button); |
| | | |
| | | if (selectedNode.writable()) { |
| | | button = new JButton("Write values"); |
| | | button.addActionListener(this); |
| | | button.setActionCommand("write"); |
| | | gbc = new GridBagConstraints(); |
| | | gbc.fill = GridBagConstraints.NONE; |
| | | gbc.gridx = 2; |
| | | gbc.gridy = GridBagConstraints.RELATIVE; |
| | | gbc.gridwidth = 1; |
| | | gbc.gridheight = 1; |
| | | gbc.weightx = 0; |
| | | gbc.weighty = 0; |
| | | gbc.anchor = GridBagConstraints.SOUTHEAST; |
| | | gbc.insets = new Insets(0, 0, 5, 5); |
| | | detailsLayout.setConstraints(button, gbc); |
| | | detailsPanel.add(button); |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | selectedNode = null; |
| | | } |
| | | |
| | | validate(); |
| | | } |
| | | |
| | | private void connect() { |
| | | ClientSap clientSap = new ClientSap(); |
| | | |
| | | InetAddress address = null; |
| | | try { |
| | | address = InetAddress.getByName(ipTextField.getText()); |
| | | } catch (UnknownHostException e1) { |
| | | e1.printStackTrace(); |
| | | return; |
| | | } |
| | | |
| | | int remotePort = 10002; |
| | | try { |
| | | remotePort = Integer.parseInt(portTextField.getText()); |
| | | if (remotePort < 1 || remotePort > 0xFFFF) { |
| | | throw new NumberFormatException("port must be in range [1, 65535]"); |
| | | } |
| | | } catch (NumberFormatException e) { |
| | | e.printStackTrace(); |
| | | return; |
| | | } |
| | | |
| | | clientSap.setTSelLocal(settingsFrame.getTselLocal()); |
| | | clientSap.setTSelRemote(settingsFrame.getTselRemote()); |
| | | |
| | | try { |
| | | association = clientSap.associate(address, remotePort, null, null); |
| | | } catch (IOException e) { |
| | | System.out.println("Error connecting to server: " + e.getMessage()); |
| | | return; |
| | | } |
| | | |
| | | ServerModel serverModel; |
| | | try { |
| | | serverModel = association.retrieveModel(); |
| | | association.getAllDataValues(); |
| | | } catch (ServiceError e) { |
| | | System.out.println("Service Error requesting model." + e.getMessage()); |
| | | association.close(); |
| | | return; |
| | | } catch (IOException e) { |
| | | System.out.println("Fatal IOException requesting model." + e.getMessage()); |
| | | return; |
| | | } |
| | | |
| | | ServerModelParser parser = new ServerModelParser(serverModel); |
| | | tree.setModel(new DefaultTreeModel(parser.getModelTree())); |
| | | |
| | | Properties lastConnectSettings = new Properties(); |
| | | FileOutputStream out = null; |
| | | try { |
| | | lastConnectSettings.setProperty(ADDRESS_KEY, ipTextField.getText()); |
| | | lastConnectSettings.setProperty(PORT_KEY, portTextField.getText()); |
| | | byte[] tsel = settingsFrame.getTselLocal(); |
| | | lastConnectSettings.setProperty(TSEL_LOCAL_KEY, tsel[0] + "," + tsel[1]); |
| | | tsel = settingsFrame.getTselRemote(); |
| | | lastConnectSettings.setProperty(TSEL_REMOTE_KEY, tsel[0] + "," + tsel[1]); |
| | | |
| | | out = new FileOutputStream(LASTCONNECTION_FILE); |
| | | lastConnectSettings.store(out, null); |
| | | } catch (IOException ex) { |
| | | System.out.println("Writing properties file failed. Reason: " + ex.getMessage()); |
| | | } finally { |
| | | try { |
| | | if (out != null) { |
| | | out.close(); |
| | | } |
| | | } catch (IOException e) { |
| | | } |
| | | } |
| | | |
| | | validate(); |
| | | } |
| | | |
| | | private void reload() { |
| | | if (selectedNode.readable()) { |
| | | try { |
| | | selectedNode.reset(association); |
| | | } catch (ServiceError e) { |
| | | System.out.println("ServiceError on reading" + e.getMessage()); |
| | | return; |
| | | } catch (IOException e) { |
| | | System.out.println("IOException on reading" + e.getMessage()); |
| | | return; |
| | | } |
| | | validate(); |
| | | } |
| | | } |
| | | |
| | | private void write() { |
| | | if (selectedNode.writable()) { |
| | | try { |
| | | selectedNode.writeValues(association); |
| | | } catch (ServiceError e) { |
| | | System.out.println("ServiceError on writing" + e.getMessage()); |
| | | return; |
| | | } catch (IOException e) { |
| | | System.out.println("IOException on writing" + e.getMessage()); |
| | | return; |
| | | } |
| | | validate(); |
| | | } |
| | | } |
| | | |
| | | private void showDataDetails(DataTreeNode node, Counter y) { |
| | | if (node.getData() != null) { |
| | | BasicDataBind<?> data = node.getData(); |
| | | JLabel nameLabel = data.getNameLabel(); |
| | | nameLabel.setText(nameLabel.getText() + ": "); |
| | | //System.out.println("1:" + nameLabel.getText()); |
| | | addDetailsComponent(nameLabel, 0, y.getValue(), 1, 1, 0, 0); |
| | | addDetailsComponent(data.getValueField(), 1, y.getValue(), 2, 1, 1, 0); |
| | | y.increment(); |
| | | } |
| | | else { |
| | | for (int i = 0; i < node.getChildCount(); i++) { |
| | | y.increment(); |
| | | DataObjectTreeNode childNode = (DataObjectTreeNode) node.getChildAt(i); |
| | | showDataDetails(childNode, childNode.toString(), y); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void showDataDetails(DataTreeNode node, String pre, Counter y) { |
| | | if (node.getData() != null) { |
| | | BasicDataBind<?> data = node.getData(); |
| | | JLabel nameLabel = data.getNameLabel(); |
| | | nameLabel.setText(pre + ": "); |
| | | //System.out.println("2:" + nameLabel.getText() + ": " + ((JTextField)data.getValueField()).getText()); |
| | | addDetailsComponent(nameLabel, 0, y.getValue(), 1, 1, 0, 0); |
| | | addDetailsComponent(data.getValueField(), 1, y.getValue(), 2, 1, 1, 0); |
| | | y.increment(); |
| | | } |
| | | else { |
| | | for (int i = 0; i < node.getChildCount(); i++) { |
| | | y.increment(); |
| | | DataObjectTreeNode childNode = (DataObjectTreeNode) node.getChildAt(i); |
| | | showDataDetails(childNode, pre + "." + childNode.toString(), y); |
| | | detailsPanel.add(new JSeparator()); |
| | | addDetailsComponent(new JSeparator(), 0, y.getValue(), 3, 1, 1, 0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void addDetailsComponent(Component c, int x, int y, int width, int height, double weightx, double weighty) { |
| | | GridBagConstraints gbc = new GridBagConstraints(); |
| | | gbc.fill = GridBagConstraints.HORIZONTAL; |
| | | gbc.gridx = x; |
| | | gbc.gridy = y; |
| | | gbc.gridwidth = width; |
| | | gbc.gridheight = height; |
| | | gbc.weightx = weightx; |
| | | gbc.weighty = weighty; |
| | | gbc.anchor = GridBagConstraints.NORTH; |
| | | gbc.insets = new Insets(3, 3, 3, 3); |
| | | detailsLayout.setConstraints(c, gbc); |
| | | detailsPanel.add(c); |
| | | } |
| | | } |
| | | /*
|
| | | * Copyright 2011-17 Fraunhofer ISE, energy & meteo Systems GmbH and other contributors
|
| | | *
|
| | | * Licensed under the Apache License, Version 2.0 (the "License");
|
| | | * you may not use this file except in compliance with the License.
|
| | | * You may obtain a copy of the License at
|
| | | *
|
| | | * http://www.apache.org/licenses/LICENSE-2.0
|
| | | *
|
| | | * Unless required by applicable law or agreed to in writing, software
|
| | | * distributed under the License is distributed on an "AS IS" BASIS,
|
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| | | * See the License for the specific language governing permissions and
|
| | | * limitations under the License.
|
| | | *
|
| | | */
|
| | | package org.openmuc.openiec61850.clientgui;
|
| | |
|
| | | import java.awt.Component;
|
| | | import java.awt.Dimension;
|
| | | import java.awt.GridBagConstraints;
|
| | | import java.awt.GridBagLayout;
|
| | | import java.awt.Insets;
|
| | | import java.awt.event.ActionEvent;
|
| | | import java.awt.event.ActionListener;
|
| | | import java.io.FileInputStream;
|
| | | import java.io.FileOutputStream;
|
| | | import java.io.IOException;
|
| | | import java.io.InputStream;
|
| | | import java.net.InetAddress;
|
| | | import java.net.UnknownHostException;
|
| | | import java.util.Properties;
|
| | |
|
| | | import javax.swing.Box;
|
| | | import javax.swing.BoxLayout;
|
| | | import javax.swing.JButton;
|
| | | import javax.swing.JFrame;
|
| | | import javax.swing.JLabel;
|
| | | import javax.swing.JPanel;
|
| | | import javax.swing.JScrollPane;
|
| | | import javax.swing.JSeparator;
|
| | | import javax.swing.JTextField;
|
| | | import javax.swing.JTree;
|
| | | import javax.swing.ToolTipManager;
|
| | | import javax.swing.UIManager;
|
| | | import javax.swing.UnsupportedLookAndFeelException;
|
| | | import javax.swing.event.TreeSelectionEvent;
|
| | | import javax.swing.event.TreeSelectionListener;
|
| | | import javax.swing.tree.DefaultMutableTreeNode;
|
| | | import javax.swing.tree.DefaultTreeModel;
|
| | |
|
| | | import org.openmuc.openiec61850.ClientAssociation;
|
| | | import org.openmuc.openiec61850.ClientSap;
|
| | | import org.openmuc.openiec61850.ServerModel;
|
| | | import org.openmuc.openiec61850.ServiceError;
|
| | | import org.openmuc.openiec61850.clientgui.util.Counter;
|
| | |
|
| | | public class ClientGui extends JFrame implements ActionListener, TreeSelectionListener {
|
| | |
|
| | | private static final String ADDRESS_KEY = "serverAddress";
|
| | | private static final String PORT_KEY = "serverPort";
|
| | | private static final String TSEL_LOCAL_KEY = "tselLocal";
|
| | | private static final String TSEL_REMOTE_KEY = "tselRemote";
|
| | | private static final String LASTCONNECTION_FILE = "lastconnection.properties";
|
| | |
|
| | | private static final long serialVersionUID = -1938913902977758367L;
|
| | |
|
| | | private final JTextField ipTextField = new JTextField("127.0.0.1");
|
| | | private final JTextField portTextField = new JTextField("10002");
|
| | | private final JTree tree = new JTree(new DefaultMutableTreeNode("No server connected"));
|
| | | private final JPanel detailsPanel = new JPanel();
|
| | | private final GridBagLayout detailsLayout = new GridBagLayout();
|
| | |
|
| | | private final SettingsFrame settingsFrame = new SettingsFrame();
|
| | |
|
| | | private ClientAssociation association;
|
| | |
|
| | | private DataTreeNode selectedNode;
|
| | |
|
| | | public ClientGui() {
|
| | | super("WHYC IEC61850 Client");
|
| | |
|
| | | Properties lastConnection = new Properties();
|
| | |
|
| | | InputStream in = null;
|
| | | try {
|
| | | in = new FileInputStream(LASTCONNECTION_FILE);
|
| | | lastConnection.load(in);
|
| | |
|
| | | ipTextField.setText(lastConnection.getProperty(ADDRESS_KEY));
|
| | | portTextField.setText(lastConnection.getProperty(PORT_KEY));
|
| | |
|
| | | String[] tselString = lastConnection.getProperty(TSEL_LOCAL_KEY).split(",");
|
| | | byte[] tsel = new byte[] { (byte) Integer.parseInt(tselString[0]), (byte) Integer.parseInt(tselString[1]) };
|
| | | settingsFrame.setTselLocal(tsel);
|
| | |
|
| | | tselString = lastConnection.getProperty(TSEL_REMOTE_KEY).split(",");
|
| | | tsel = new byte[] { (byte) Integer.parseInt(tselString[0]), (byte) Integer.parseInt(tselString[1]) };
|
| | | settingsFrame.setTselRemote(tsel);
|
| | | } catch (Exception ex) {
|
| | | // no lastconnection.properties file found, use default.
|
| | | } finally {
|
| | | try {
|
| | | if (in != null) {
|
| | | in.close();
|
| | | }
|
| | | } catch (IOException e) {
|
| | | e.printStackTrace();
|
| | |
|
| | | }
|
| | | }
|
| | |
|
| | | try {
|
| | | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
| | | } catch (ClassNotFoundException e) {
|
| | | System.out.println("Class not found: " + e.getMessage());
|
| | | } catch (InstantiationException e) {
|
| | | System.out.println("Object not instantiated: " + e.getMessage());
|
| | | } catch (IllegalAccessException e) {
|
| | | System.out.println("Illegal acces: " + e.getMessage());
|
| | | } catch (UnsupportedLookAndFeelException e) {
|
| | | System.out.println("Unsupported LookAndFeel: " + e.getMessage());
|
| | | }
|
| | |
|
| | | GridBagLayout gbl = new GridBagLayout();
|
| | | setLayout(gbl);
|
| | |
|
| | | JPanel topPanel = new JPanel();
|
| | | topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
|
| | |
|
| | | GridBagConstraints topPanelConstraint = new GridBagConstraints();
|
| | | topPanelConstraint.fill = GridBagConstraints.HORIZONTAL;
|
| | | topPanelConstraint.gridwidth = GridBagConstraints.REMAINDER;
|
| | | topPanelConstraint.gridx = 0;
|
| | | topPanelConstraint.gridy = 0;
|
| | | topPanelConstraint.insets = new Insets(5, 5, 5, 5);
|
| | | topPanelConstraint.anchor = GridBagConstraints.NORTH;
|
| | | gbl.setConstraints(topPanel, topPanelConstraint);
|
| | | add(topPanel);
|
| | |
|
| | | JLabel label = new JLabel("IP: ");
|
| | | topPanel.add(label);
|
| | | topPanel.add(ipTextField);
|
| | | topPanel.add(Box.createRigidArea(new Dimension(5, 0)));
|
| | |
|
| | | label = new JLabel("Port: ");
|
| | | topPanel.add(label);
|
| | | topPanel.add(portTextField);
|
| | | topPanel.add(Box.createRigidArea(new Dimension(5, 0)));
|
| | |
|
| | | JButton newServerButton = new JButton("Connect to Server");
|
| | | newServerButton.addActionListener(this);
|
| | | newServerButton.setActionCommand("Connect");
|
| | | topPanel.add(newServerButton);
|
| | | topPanel.add(Box.createRigidArea(new Dimension(5, 0)));
|
| | |
|
| | | JButton settingsButton = new JButton("Settings");
|
| | | settingsButton.addActionListener(this);
|
| | | settingsButton.setActionCommand("Settings");
|
| | | topPanel.add(settingsButton);
|
| | |
|
| | | ToolTipManager.sharedInstance().registerComponent(tree);
|
| | |
|
| | | tree.setCellRenderer(new DataObjectTreeCellRenderer());
|
| | | tree.setMinimumSize(new Dimension(100, 0));
|
| | | tree.addTreeSelectionListener(this);
|
| | | JScrollPane treeScrollPane = new JScrollPane(tree);
|
| | | treeScrollPane.setMinimumSize(new Dimension(100, 0));
|
| | | treeScrollPane.setVisible(true);
|
| | |
|
| | | GridBagConstraints treeScrollPaneConstraint = new GridBagConstraints();
|
| | | treeScrollPaneConstraint.fill = GridBagConstraints.BOTH;
|
| | | treeScrollPaneConstraint.gridx = 0;
|
| | | treeScrollPaneConstraint.gridy = 1;
|
| | | treeScrollPaneConstraint.weightx = 0.2;
|
| | | treeScrollPaneConstraint.weighty = 1;
|
| | | treeScrollPaneConstraint.insets = new Insets(5, 5, 5, 5);
|
| | | gbl.setConstraints(treeScrollPane, treeScrollPaneConstraint);
|
| | | add(treeScrollPane);
|
| | |
|
| | | detailsPanel.setLayout(detailsLayout);
|
| | | detailsPanel.setAlignmentY(TOP_ALIGNMENT);
|
| | | JScrollPane detailsScrollPane = new JScrollPane(detailsPanel);
|
| | | detailsPanel.setMaximumSize(detailsScrollPane.getSize());
|
| | | detailsScrollPane.setMinimumSize(new Dimension(0, 0));
|
| | | detailsScrollPane.setPreferredSize(new Dimension(200, 0));
|
| | | detailsScrollPane.setVisible(true);
|
| | | GridBagConstraints detailsScrollPaneConstraint = new GridBagConstraints();
|
| | | detailsScrollPaneConstraint.fill = GridBagConstraints.BOTH;
|
| | | detailsScrollPaneConstraint.gridx = 1;
|
| | | detailsScrollPaneConstraint.gridy = 1;
|
| | | detailsScrollPaneConstraint.weightx = 0.8;
|
| | | detailsScrollPaneConstraint.weighty = 1;
|
| | | detailsScrollPaneConstraint.insets = new Insets(5, 5, 5, 5);
|
| | | gbl.setConstraints(detailsScrollPane, detailsScrollPaneConstraint);
|
| | | add(detailsScrollPane);
|
| | |
|
| | | // Display the window.
|
| | | setSize(700, 500);
|
| | | setMinimumSize(new Dimension(420, 0));
|
| | | setVisible(true);
|
| | | }
|
| | |
|
| | | public static void main(String[] args) {
|
| | | ClientGui clientGui = new ClientGui();
|
| | | clientGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
| | | clientGui.setVisible(true);
|
| | | }
|
| | |
|
| | | @Override
|
| | | public void actionPerformed(ActionEvent arg0) {
|
| | | if ("connect".equalsIgnoreCase(arg0.getActionCommand())) {
|
| | | connect();
|
| | | }
|
| | | else if ("reload".equalsIgnoreCase(arg0.getActionCommand())) {
|
| | | reload();
|
| | | }
|
| | | else if ("write".equalsIgnoreCase(arg0.getActionCommand())) {
|
| | | write();
|
| | | }
|
| | | else if ("settings".equalsIgnoreCase(arg0.getActionCommand())) {
|
| | | settingsFrame.setVisible(true);
|
| | | }
|
| | | }
|
| | |
|
| | | @Override
|
| | | public void valueChanged(TreeSelectionEvent e) {
|
| | | detailsPanel.removeAll();
|
| | | detailsPanel.repaint();
|
| | | if (e.getNewLeadSelectionPath() != null) {
|
| | | selectedNode = (DataTreeNode) e.getNewLeadSelectionPath().getLastPathComponent();
|
| | | if (selectedNode.readable()) {
|
| | | showDataDetails(selectedNode, new Counter());
|
| | |
|
| | | JPanel filler = new JPanel();
|
| | | GridBagConstraints gbc = new GridBagConstraints();
|
| | | gbc.fill = GridBagConstraints.BOTH;
|
| | | gbc.gridx = 0;
|
| | | gbc.gridy = GridBagConstraints.RELATIVE;
|
| | | gbc.gridwidth = 3;
|
| | | gbc.gridheight = 1;
|
| | | gbc.weightx = 0;
|
| | | gbc.weighty = 1;
|
| | | detailsLayout.setConstraints(filler, gbc);
|
| | | detailsPanel.add(filler);
|
| | |
|
| | | JButton button = new JButton("Reload values");
|
| | | button.addActionListener(this);
|
| | | button.setActionCommand("reload");
|
| | | gbc = new GridBagConstraints();
|
| | | gbc.fill = GridBagConstraints.NONE;
|
| | | gbc.gridx = 0;
|
| | | gbc.gridy = GridBagConstraints.RELATIVE;
|
| | | gbc.gridwidth = 2;
|
| | | gbc.gridheight = 1;
|
| | | gbc.weightx = 0;
|
| | | gbc.weighty = 0;
|
| | | gbc.anchor = GridBagConstraints.SOUTHWEST;
|
| | | gbc.insets = new Insets(0, 5, 5, 0);
|
| | | detailsLayout.setConstraints(button, gbc);
|
| | | detailsPanel.add(button);
|
| | |
|
| | | if (selectedNode.writable()) {
|
| | | button = new JButton("Write values");
|
| | | button.addActionListener(this);
|
| | | button.setActionCommand("write");
|
| | | gbc = new GridBagConstraints();
|
| | | gbc.fill = GridBagConstraints.NONE;
|
| | | gbc.gridx = 2;
|
| | | gbc.gridy = GridBagConstraints.RELATIVE;
|
| | | gbc.gridwidth = 1;
|
| | | gbc.gridheight = 1;
|
| | | gbc.weightx = 0;
|
| | | gbc.weighty = 0;
|
| | | gbc.anchor = GridBagConstraints.SOUTHEAST;
|
| | | gbc.insets = new Insets(0, 0, 5, 5);
|
| | | detailsLayout.setConstraints(button, gbc);
|
| | | detailsPanel.add(button);
|
| | | }
|
| | | }
|
| | | }
|
| | | else {
|
| | | selectedNode = null;
|
| | | }
|
| | |
|
| | | validate();
|
| | | }
|
| | |
|
| | | private void connect() {
|
| | | ClientSap clientSap = new ClientSap();
|
| | |
|
| | | InetAddress address = null;
|
| | | try {
|
| | | address = InetAddress.getByName(ipTextField.getText());
|
| | | } catch (UnknownHostException e1) {
|
| | | e1.printStackTrace();
|
| | | return;
|
| | | }
|
| | |
|
| | | int remotePort = 10002;
|
| | | try {
|
| | | remotePort = Integer.parseInt(portTextField.getText());
|
| | | if (remotePort < 1 || remotePort > 0xFFFF) {
|
| | | throw new NumberFormatException("port must be in range [1, 65535]");
|
| | | }
|
| | | } catch (NumberFormatException e) {
|
| | | e.printStackTrace();
|
| | | return;
|
| | | }
|
| | |
|
| | | clientSap.setTSelLocal(settingsFrame.getTselLocal());
|
| | | clientSap.setTSelRemote(settingsFrame.getTselRemote());
|
| | |
|
| | | try {
|
| | | association = clientSap.associate(address, remotePort, null, null);
|
| | | } catch (IOException e) {
|
| | | System.out.println("Error connecting to server: " + e.getMessage());
|
| | | return;
|
| | | }
|
| | |
|
| | | ServerModel serverModel;
|
| | | try {
|
| | | serverModel = association.retrieveModel();
|
| | | association.getAllDataValues();
|
| | | } catch (ServiceError e) {
|
| | | System.out.println("Service Error requesting model." + e.getMessage());
|
| | | association.close();
|
| | | return;
|
| | | } catch (IOException e) {
|
| | | System.out.println("Fatal IOException requesting model." + e.getMessage());
|
| | | return;
|
| | | }
|
| | |
|
| | | ServerModelParser parser = new ServerModelParser(serverModel);
|
| | | tree.setModel(new DefaultTreeModel(parser.getModelTree()));
|
| | |
|
| | | Properties lastConnectSettings = new Properties();
|
| | | FileOutputStream out = null;
|
| | | try {
|
| | | lastConnectSettings.setProperty(ADDRESS_KEY, ipTextField.getText());
|
| | | lastConnectSettings.setProperty(PORT_KEY, portTextField.getText());
|
| | | byte[] tsel = settingsFrame.getTselLocal();
|
| | | lastConnectSettings.setProperty(TSEL_LOCAL_KEY, tsel[0] + "," + tsel[1]);
|
| | | tsel = settingsFrame.getTselRemote();
|
| | | lastConnectSettings.setProperty(TSEL_REMOTE_KEY, tsel[0] + "," + tsel[1]);
|
| | |
|
| | | out = new FileOutputStream(LASTCONNECTION_FILE);
|
| | | lastConnectSettings.store(out, null);
|
| | | } catch (IOException ex) {
|
| | | System.out.println("Writing properties file failed. Reason: " + ex.getMessage());
|
| | | } finally {
|
| | | try {
|
| | | if (out != null) {
|
| | | out.close();
|
| | | }
|
| | | } catch (IOException e) {
|
| | | }
|
| | | }
|
| | |
|
| | | validate();
|
| | | }
|
| | |
|
| | | private void reload() {
|
| | | if (selectedNode.readable()) {
|
| | | try {
|
| | | selectedNode.reset(association);
|
| | | } catch (ServiceError e) {
|
| | | System.out.println("ServiceError on reading" + e.getMessage());
|
| | | return;
|
| | | } catch (IOException e) {
|
| | | System.out.println("IOException on reading" + e.getMessage());
|
| | | return;
|
| | | }
|
| | | validate();
|
| | | }
|
| | | }
|
| | |
|
| | | private void write() {
|
| | | if (selectedNode.writable()) {
|
| | | try {
|
| | | selectedNode.writeValues(association);
|
| | | } catch (ServiceError e) {
|
| | | System.out.println("ServiceError on writing" + e.getMessage());
|
| | | return;
|
| | | } catch (IOException e) {
|
| | | System.out.println("IOException on writing" + e.getMessage());
|
| | | return;
|
| | | }
|
| | | validate();
|
| | | }
|
| | | }
|
| | |
|
| | | private void showDataDetails(DataTreeNode node, Counter y) {
|
| | | if (node.getData() != null) {
|
| | | BasicDataBind<?> data = node.getData();
|
| | | JLabel nameLabel = data.getNameLabel();
|
| | | nameLabel.setText(nameLabel.getText() + ": ");
|
| | | //System.out.println("1:" + nameLabel.getText());
|
| | | addDetailsComponent(nameLabel, 0, y.getValue(), 1, 1, 0, 0);
|
| | | addDetailsComponent(data.getValueField(), 1, y.getValue(), 2, 1, 1, 0);
|
| | | y.increment();
|
| | | }
|
| | | else {
|
| | | for (int i = 0; i < node.getChildCount(); i++) {
|
| | | y.increment();
|
| | | DataObjectTreeNode childNode = (DataObjectTreeNode) node.getChildAt(i);
|
| | | showDataDetails(childNode, childNode.toString(), y);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | private void showDataDetails(DataTreeNode node, String pre, Counter y) {
|
| | | if (node.getData() != null) {
|
| | | BasicDataBind<?> data = node.getData();
|
| | | JLabel nameLabel = data.getNameLabel();
|
| | | nameLabel.setText(pre + ": ");
|
| | | //System.out.println("2:" + nameLabel.getText() + ": " + ((JTextField)data.getValueField()).getText());
|
| | | addDetailsComponent(nameLabel, 0, y.getValue(), 1, 1, 0, 0);
|
| | | addDetailsComponent(data.getValueField(), 1, y.getValue(), 2, 1, 1, 0);
|
| | | y.increment();
|
| | | }
|
| | | else {
|
| | | for (int i = 0; i < node.getChildCount(); i++) {
|
| | | y.increment();
|
| | | DataObjectTreeNode childNode = (DataObjectTreeNode) node.getChildAt(i);
|
| | | showDataDetails(childNode, pre + "." + childNode.toString(), y);
|
| | | detailsPanel.add(new JSeparator());
|
| | | addDetailsComponent(new JSeparator(), 0, y.getValue(), 3, 1, 1, 0);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | private void addDetailsComponent(Component c, int x, int y, int width, int height, double weightx, double weighty) {
|
| | | GridBagConstraints gbc = new GridBagConstraints();
|
| | | gbc.fill = GridBagConstraints.HORIZONTAL;
|
| | | gbc.gridx = x;
|
| | | gbc.gridy = y;
|
| | | gbc.gridwidth = width;
|
| | | gbc.gridheight = height;
|
| | | gbc.weightx = weightx;
|
| | | gbc.weighty = weighty;
|
| | | gbc.anchor = GridBagConstraints.NORTH;
|
| | | gbc.insets = new Insets(3, 3, 3, 3);
|
| | | detailsLayout.setConstraints(c, gbc);
|
| | | detailsPanel.add(c);
|
| | | }
|
| | | }
|