Package xplanetconfigurator.gui

Source Code of xplanetconfigurator.gui.JPanelControlDownloaderArcs

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

/*
* JPanelAll.java
*
* Created on 27.04.2009, 22:13:10
*/
package xplanetconfigurator.gui;

import java.awt.GridBagConstraints;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.text.JTextComponent;
import xplanetconfigurator.util.OwnPreferences;

/**
*
* @author tom
*/
public class JPanelControlDownloaderArcs extends ControlPanel implements IAskForUserTextLine {

    private static final String GUI_DIVIDER_LOCATION_HORIZONTAL = "arcs.gui_divider_location_horizontal";
    private Logger logger;
    private List markerPanels;
    int markerCountGridY = 1;
    boolean addMarker;
    boolean isAddingPixelForAlignmentRefresh;
    private String downloadIntervallTmpForNewMarkers;

    /** Creates new form JPanelAll */
    public JPanelControlDownloaderArcs(MainFrame mainFrame) {
        super(mainFrame);
        initComponents();
        this.logger = Logger.getLogger(this.getClass().getName());
        this.markerPanels = new ArrayList();
        this.addMarkerPanels();
        this.loadUserPrefs();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jSplitPaneMain = new javax.swing.JSplitPane();
        jPanelControls = new javax.swing.JPanel();
        jPanelWait = new javax.swing.JPanel();
        jLabelWait = new javax.swing.JLabel();
        jTextFieldWait = new javax.swing.JTextField();
        jLabelMinutes = new javax.swing.JLabel();
        jPanelMarkersAndButtons = new javax.swing.JPanel();
        jPanelAddRemove = new javax.swing.JPanel();
        jButtonAdd = new javax.swing.JButton();
        jButtonRemove = new javax.swing.JButton();
        jScrollPanelMarkers = new javax.swing.JScrollPane();
        jPanelMarkers = new javax.swing.JPanel();
        jPanelPlaceholder = new javax.swing.JPanel();
        jPanelHelp = new javax.swing.JPanel();
        jLabelHelp = new javax.swing.JLabel();
        jScrollPane = new javax.swing.JScrollPane();
        jTextAreaHelp = new javax.swing.JTextArea();

        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentHidden(java.awt.event.ComponentEvent evt) {
                formComponentHidden(evt);
            }
            public void componentShown(java.awt.event.ComponentEvent evt) {
                formComponentShown(evt);
            }
        });
        setLayout(new java.awt.GridBagLayout());

        jSplitPaneMain.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPaneMain.setName("jSplitPaneMain"); // NOI18N

        jPanelControls.setName("jPanelControls"); // NOI18N
        jPanelControls.setLayout(new java.awt.GridBagLayout());

        jPanelWait.setName("jPanelWait"); // NOI18N
        jPanelWait.setLayout(new java.awt.GridBagLayout());

        jLabelWait.setText("Download Intervall"); // NOI18N
        jLabelWait.setName("jLabelWait"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanelWait.add(jLabelWait, gridBagConstraints);

        jTextFieldWait.setMinimumSize(new java.awt.Dimension(70, 20));
        jTextFieldWait.setName("jTextFieldWait"); // NOI18N
        jTextFieldWait.setPreferredSize(new java.awt.Dimension(70, 20));
        jTextFieldWait.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                jTextFieldWaitCaretUpdate(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        jPanelWait.add(jTextFieldWait, gridBagConstraints);

        jLabelMinutes.setText("minutes");
        jLabelMinutes.setName("jLabelMinutes"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        jPanelWait.add(jLabelMinutes, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        jPanelControls.add(jPanelWait, gridBagConstraints);

        jPanelMarkersAndButtons.setBorder(javax.swing.BorderFactory.createTitledBorder("Arcs"));
        jPanelMarkersAndButtons.setName("jPanelMarkersAndButtons"); // NOI18N
        jPanelMarkersAndButtons.setLayout(new java.awt.GridBagLayout());

        jPanelAddRemove.setName("jPanelAddRemove"); // NOI18N
        jPanelAddRemove.setLayout(new java.awt.GridBagLayout());

        jButtonAdd.setIcon(new javax.swing.ImageIcon(getClass().getResource("/xplanetconfigurator/gui/resources/img/Button-Add-16x16.gif"))); // NOI18N
        jButtonAdd.setToolTipText("Add Marker");
        jButtonAdd.setName("jButtonAdd"); // NOI18N
        jButtonAdd.setPreferredSize(new java.awt.Dimension(25, 25));
        jButtonAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAddActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        jPanelAddRemove.add(jButtonAdd, gridBagConstraints);

        jButtonRemove.setIcon(new javax.swing.ImageIcon(getClass().getResource("/xplanetconfigurator/gui/resources/img/Button-Delete-16x16.gif"))); // NOI18N
        jButtonRemove.setToolTipText("Remove Marker");
        jButtonRemove.setName("jButtonRemove"); // NOI18N
        jButtonRemove.setPreferredSize(new java.awt.Dimension(25, 25));
        jButtonRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonRemoveActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        jPanelAddRemove.add(jButtonRemove, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        jPanelMarkersAndButtons.add(jPanelAddRemove, gridBagConstraints);

        jScrollPanelMarkers.setMinimumSize(new java.awt.Dimension(23, 120));
        jScrollPanelMarkers.setName("jScrollPanelMarkers"); // NOI18N
        jScrollPanelMarkers.setPreferredSize(new java.awt.Dimension(23, 120));

        jPanelMarkers.setName("jPanelMarkers"); // NOI18N
        jPanelMarkers.setLayout(new java.awt.GridBagLayout());

        jPanelPlaceholder.setName("jPanelPlaceholder"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 99;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weighty = 1.0;
        jPanelMarkers.add(jPanelPlaceholder, gridBagConstraints);

        jScrollPanelMarkers.setViewportView(jPanelMarkers);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weighty = 1.0;
        jPanelMarkersAndButtons.add(jScrollPanelMarkers, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelControls.add(jPanelMarkersAndButtons, gridBagConstraints);

        jSplitPaneMain.setLeftComponent(jPanelControls);

        jPanelHelp.setName("jPanelHelp"); // NOI18N
        jPanelHelp.setLayout(new java.awt.GridBagLayout());

        jLabelHelp.setText("Help Text");
        jLabelHelp.setName("jLabelHelp"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanelHelp.add(jLabelHelp, gridBagConstraints);

        jScrollPane.setName("jScrollPane"); // NOI18N

        jTextAreaHelp.setColumns(20);
        jTextAreaHelp.setEditable(false);
        jTextAreaHelp.setRows(5);
        jTextAreaHelp.setText("Download Intervall\nIs in minutes. If the text field is empty the downloader takes 180 minutes\n(3 hours) as default. Applies for all markers.\nFor the eclipse from\nhttp://www.wizabit.eclipse.co.uk/xplanet/pages/marker.html\nyou could choose a long intervall  because an  eclipse does not happen often\non earth.\n\nAdd/Remove an Arc File\n- To add an arc file press the upper \"+\" button. Type a name in the dialog.\nAdd a URL to the combo box. Example:\nname:\teclipse\nURL:\thttp://www.wizabit.eclipse.co.uk/xplanet/files/local/arcs/eclipse\n- To remove a marker press the upper \"-\" button.\n\nRemember this is the download only. If you want o see the arc you\nhave to set at least the parameter \"arc_file\" in the config file.\nPlease refer to the XPlanet parameters below that are related to the clouds.\n\nAdditionally\nThe arc_file can be used in conjunction with a marker file drawing the\neclipse onto the globe. You would use a marker (not arc). Define the\ndownload under \"markers\" not \"arcs\". There you should have:\nname:\teclipse\nURL:\thttp://www.wizabit.eclipse.co.uk/xplanet/files/local/eclipse\nPlease refer to\n- http://www.wizabit.eclipse.co.uk/xplanet/pages/marker.html\n- help text for markers\n\n\n---XPlanet Parameters in Config File---\n\narc_color\nSpecify the default color for great arcs.  This color will be\noverridden if a color is specified for an arc in the arc file.  The\ncolor may be specified either as a name, a hexadecimal number, or as\nan RGB triple.  For example, arc_color=red, arc_color=0xff0000, and\narc_color={255,0,0} all mean the same thing.  The default value is\nwhite.\n\narc_file\nSpecify a great arc file for this planet.  This option may be used\nmore than once.  See the README and sample files in the xplanet/arcs\ndirectory for more information.  The default is no arc files."); // NOI18N
        jTextAreaHelp.setName("jTextAreaHelp"); // NOI18N
        jScrollPane.setViewportView(jTextAreaHelp);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelHelp.add(jScrollPane, gridBagConstraints);

        jSplitPaneMain.setRightComponent(jPanelHelp);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(jSplitPaneMain, gridBagConstraints);
    }// </editor-fold>//GEN-END:initComponents

    private void formComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentShown
        this.receiveCommandLineParameters();
    }//GEN-LAST:event_formComponentShown

    private void jTextFieldWaitCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_jTextFieldWaitCaretUpdate
        if (this.jTextFieldWait.hasFocus()) {
            this.sendDownloadParamterWait();
        }
    }//GEN-LAST:event_jTextFieldWaitCaretUpdate

    private void jButtonAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAddActionPerformed
        this.addMarker = true;
        JDialogTextLineInput dialog = new JDialogTextLineInput("Add an Arc File. Please give a Name", this);
        dialog.setVisible(true);
    }//GEN-LAST:event_jButtonAddActionPerformed

    private void jButtonRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRemoveActionPerformed
        this.addMarker = false;
        JDialogTextLineInput dialog = new JDialogTextLineInput("Remove an Arc File. Please give a Name", this);
        dialog.setVisible(true);
    }//GEN-LAST:event_jButtonRemoveActionPerformed

    private void formComponentHidden(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentHidden
        this.saveUserPrefs();
    }//GEN-LAST:event_formComponentHidden

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonAdd;
    private javax.swing.JButton jButtonRemove;
    private javax.swing.JLabel jLabelHelp;
    private javax.swing.JLabel jLabelMinutes;
    private javax.swing.JLabel jLabelWait;
    private javax.swing.JPanel jPanelAddRemove;
    private javax.swing.JPanel jPanelControls;
    private javax.swing.JPanel jPanelHelp;
    private javax.swing.JPanel jPanelMarkers;
    private javax.swing.JPanel jPanelMarkersAndButtons;
    private javax.swing.JPanel jPanelPlaceholder;
    private javax.swing.JPanel jPanelWait;
    private javax.swing.JScrollPane jScrollPane;
    private javax.swing.JScrollPane jScrollPanelMarkers;
    private javax.swing.JSplitPane jSplitPaneMain;
    private javax.swing.JTextArea jTextAreaHelp;
    private javax.swing.JTextField jTextFieldWait;
    // End of variables declaration//GEN-END:variables

    /**
     * Analyse the configuration of the downloader and set the values of
     * the markers accordingly.
     *
     * @param parameters
     * @return
     */
    @Override
    boolean receiveCommandLineParameters(String parameters) {
        // Update the Status
        String params = this.getMainFrame().getDownloaderConfig();
        // Take any markerPanel for the wait
        String regExpr = "(?i)(arcs\\.\\w+.wait=)(\\S+)";
        String found = this.receiveParameter(params, regExpr, this.jTextFieldWait, 2);
        // TODO: Call all markers
        Iterator it = this.markerPanels.iterator();
        while (it.hasNext()) {
            JPanelControlDownloaderArc markerPanel = (JPanelControlDownloaderArc) it.next();
            markerPanel.receiveCommandLineParameters(parameters);
        }
        if (found != null) {
            this.downloadIntervallTmpForNewMarkers = found;
            return true;
        } else {
            this.downloadIntervallTmpForNewMarkers = "180";
            this.jTextFieldWait.setText("180");
            return false;
        }
    }

    private void sendDownloadParamterWait() {
        Iterator it = this.markerPanels.iterator();
        while (it.hasNext()) {
            JPanelControlDownloaderArc markerPanel = (JPanelControlDownloaderArc) it.next();
            this.sendDownloadParameter(
                    this.jTextFieldWait,
                    "(arcs\\." + markerPanel.getMarkerName() + "\\.wait=)(.*)",
                    "arcs." + markerPanel.getMarkerName() + ".wait");
        }
    }

    public String getText() {
        return this.jTextAreaHelp.getText();
    }

    public JTextComponent getTextComponent() {
        return this.jTextAreaHelp;
    }

    @Override
    public boolean isDownloaderControlPanel() {
        return true;
    }

    /**
     * Called at intial load depending on the Uploader (config of uploader)
     * and if the user adds a markerPanel by pressing the add button
     */
    private void addMarkerPanels() {
        // Read the config and add the arcs found in the text of the config (file)
        // of the uploader.
        String params = this.getMainFrame().getDownloaderConfig();
        // Find all arcs
        String regExpr = "(?i)(?m)^(arcs\\.)(\\w+)";
        Pattern p = Pattern.compile(regExpr);
        Matcher m = p.matcher(params);
        List names = new ArrayList();
        while (m.find()) {
            String s = m.group(2);
            if (names.contains(s)) {
                continue;
            }
            this.logger.finer("Found marker named: " + s);
            names.add(s);
        }
        Iterator it = names.iterator();
        while (it.hasNext()) {
            String panelName = (String) it.next();
            this.addMarkerPanel(panelName);
        }
    }

    private void alignMarkers() {
        Iterator it = this.markerPanels.iterator();
        int maxWidth = 0;
        while (it.hasNext()) {
            JPanelControlDownloaderArc marker = (JPanelControlDownloaderArc) it.next();
            int w = marker.getWidthOfJLabelMarkerName();
            if (w > maxWidth) {
                maxWidth = w;
            }
        }
        it = this.markerPanels.iterator();
        while (it.hasNext()) {
            JPanelControlDownloaderArc markerPanel = (JPanelControlDownloaderArc) it.next();
            markerPanel.setWidthOfJLabelMarkerName(maxWidth);
            markerPanel.validate();
        }

        // This all does not work to repaint the alignment of the marker.
//        this.jPanelMarkers.validate();
//        this.jPanelMarkers.validate();

        // TODO: Do it like intended by swing
        //       The alignment drove me crazy
        int h = this.jPanelMarkers.getHeight();
        int w = this.jPanelMarkers.getWidth();
        if (isAddingPixelForAlignmentRefresh) {
            this.jPanelMarkers.setSize(w + 1, h);
            isAddingPixelForAlignmentRefresh = false;
        } else {
            this.jPanelMarkers.setSize(w - 1, h);
            isAddingPixelForAlignmentRefresh = true;
        }
    }

    /**
     * Called at intial load depending on the Uploader (config of uploader)
     * and if the user adds a markerPanel by pressing the add button
     */
    private void addMarkerPanel(String markerName) {
        JPanelControlDownloaderArc markerPanel = new JPanelControlDownloaderArc(this.getMainFrame(), markerName, this);
        this.markerPanels.add(markerPanel);

        GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = this.markerCountGridY++;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weightx = 1.0;
        this.jPanelMarkers.add(markerPanel, gridBagConstraints);
        // Import for aligning the markers. It not called the label to allign
        // has 0 with and hight and will not be visible.
        this.jPanelMarkers.validate();
    }

    private void removeMarkerPanel(String markerNameToRemove) {
        Iterator it = this.markerPanels.iterator();
        while (it.hasNext()) {
            JPanelControlDownloaderArc markerPanel = (JPanelControlDownloaderArc) it.next();
            String s = markerPanel.getMarkerName();
            if (s.equalsIgnoreCase(markerNameToRemove)) {
                this.jPanelMarkers.remove(markerPanel);
                this.markerPanels.remove(markerPanel);
                this.removeMarkerFromUplaoder(s, "arcs");
                this.jPanelMarkers.validate();
                return;
            }
        }
    }

    /**
     * Add or remove a markerPanel after the user opened a Dialog.
     * @param nameFromDialog
     */
    public void receiveUserTextLine(String nameFromDialog) {
        // do not allow blanks
        nameFromDialog = nameFromDialog.replaceAll("\\s+", "");
        if (nameFromDialog.equals("")) {
            //Do nothing
            return;
        }
        nameFromDialog = nameFromDialog.toLowerCase();
        // Check wether to remove markerPanel
        if (!this.addMarker) {
            this.removeMarkerPanel(nameFromDialog);
            this.updateConfiguration();
            return;
        }
        // Add markerPanel
        // Check if other arcs carry the same name
        Iterator it = this.markerPanels.iterator();
        while (it.hasNext()) {
            JPanelControlDownloaderArc marker = (JPanelControlDownloaderArc) it.next();
            String s = marker.getMarkerName();
            if (s.equalsIgnoreCase(nameFromDialog)) {
                this.popError("A marker of this name does exits.\nChoose another name.");
                return;
            }
        }
        // Check the whole downloader config for double names
        boolean exists = this.checkIfNameOfMarkerExists(nameFromDialog, "arcs");
        if (exists) {
            this.popError("An arc named like this does exits.\nChoose another name.");
            return;
        }
        this.addMarkerPanel(nameFromDialog);
        this.alignMarkers();
        this.jPanelMarkers.validate();
        this.updateConfiguration();
    }

    private void loadUserPrefs() {
        logger.finer("Getting user preferences...");
        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass())// Position an size of frame

        int i = prefs.getInt(JPanelControlDownloaderArcs.GUI_DIVIDER_LOCATION_HORIZONTAL, 300);
        this.jSplitPaneMain.setDividerLocation(i);
    }

    private void saveUserPrefs() {
        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass());
        prefs.putInt(JPanelControlDownloaderArcs.GUI_DIVIDER_LOCATION_HORIZONTAL, this.jSplitPaneMain.getDividerLocation());
    }

    /**
     * Updates the section (earth, moon,....) in the configuration by
     * adding/changing/removing the arc_file in this section.
     */
    public void updateConfiguration() {
        Iterator it = this.markerPanels.iterator();
        String keyValuePairs = "";
        while (it.hasNext()) {
            JPanelControlDownloaderArc marker = (JPanelControlDownloaderArc) it.next();
            String markerURL = marker.getCurrentURL();
            String fileName = getFileNameOfURL(markerURL);
            if (fileName == null) {
                continue;
            }
            // Do not allow blanks
            // fileName = fileName.replaceAll("\\s+", "");
            if (markerURL != null) {
                if (keyValuePairs.length() > 0) {
                    keyValuePairs = keyValuePairs + "\n";
                }
                keyValuePairs = keyValuePairs + "arc_file=" + fileName;
            }

        }
        this.logger.finer("Update arc files of section default with key-value-pairs of '" + keyValuePairs + "'.");
        sendConfigParameter("default", keyValuePairs, "(?i)(arc_file=)(\\S*)");
    }

    @Override
    void receiveCommandLineParameters() {
        String params = this.getMainFrame().getDownloaderConfig();
        this.receiveCommandLineParameters(params);
        if (this.isShowing()) {
            this.alignMarkers();
        }
    }
}
TOP

Related Classes of xplanetconfigurator.gui.JPanelControlDownloaderArcs

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.