Java tutorial
/* * Copyright 2015 Patrik Karlsson. * * 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 se.trixon.toolbox.geotagger; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDropEvent; import java.io.File; import java.io.IOException; import java.nio.charset.MalformedInputException; import java.util.List; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.TableColumnModel; import javax.swing.table.TableRowSorter; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.netbeans.api.settings.ConvertAsProperties; import org.openide.util.Exceptions; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.windows.*; import se.trixon.almond.dialogs.Message; import se.trixon.almond.dialogs.SimpleDialog; import se.trixon.almond.dictionary.Dict; import se.trixon.almond.icon.Pict; import se.trixon.almond.swing.NumericTableCellRenderer; import se.trixon.toolbox.core.base.ToolTopComponent; import se.trixon.toolbox.io.file.pxy.Pxy; /** * Top component which displays something. */ @ConvertAsProperties(dtd = "-//se.trixon.toolbox.geotagger//Geotagger//EN", autostore = false) @TopComponent.Description(preferredID = "GeotaggerTopComponent", //iconBase="SET/PATH/TO/ICON/HERE", persistenceType = TopComponent.PERSISTENCE_ALWAYS) @TopComponent.Registration(mode = "editor", openAtStartup = false) public final class GeotaggerTopComponent extends ToolTopComponent implements OperationListener { private static final int ICON_SIZE = TOOLBAR_ICON_SIZE; private final GeotaggerController mController; private File mSource; private GeotagTableModel mTableModel; private final Options mOptions = Options.INSTANCE; private TableRowSorter<GeotagTableModel> mTableRowSorter; public GeotaggerTopComponent() { mBundle = NbBundle.getBundle(GeotaggerController.class); mToolName = mBundle.getString("Tool-Name"); initComponents(); setName(mToolName); mController = new GeotaggerController(this); init(); File file = new File(FileUtils.getUserDirectory(), "GeotaggerDemo.csv"); if (file.exists()) { openFile(file); } } @Override public HelpCtx getHelpCtx() { return new HelpCtx("se.trixon.toolbox.geotagger.about"); } @Override public void onOperationFailed(String message) { logAppend(message); } @Override public void onOperationFinished(String message) { logAppend(message); makeBusy(false); boolean state = true; openButton.setEnabled(state); editToggleButton.setEnabled(state); saveLogButton.setEnabled(state); closeButton.setEnabled(state); startButton.setEnabled(state); new Thread(() -> { Message.information(Dict.OPERATION_COMPLETED.getString(), message); }).start(); } @Override public void onOperationInterrupted() { } @Override public void onOperationLog(String message) { logAppend(message); } @Override public void onOperationProcessingStarted() { } @Override public void onOperationStarted() { makeBusy(true); boolean state = false; openButton.setEnabled(state); editToggleButton.setEnabled(state); saveLogButton.setEnabled(state); closeButton.setEnabled(state); startButton.setEnabled(state); } private void init() { openButton.setIcon(Pict.Actions.DOCUMENT_OPEN.get(TOOLBAR_ICON_SIZE)); editToggleButton.setIcon(Pict.Actions.DOCUMENT_EDIT.get(TOOLBAR_ICON_SIZE)); closeButton.setIcon(Pict.Actions.WINDOW_CLOSE.get(TOOLBAR_ICON_SIZE)); closeButton.setEnabled(false); startButton.setIcon(Pict.Actions.ARROW_RIGHT.get(ICON_SIZE)); startButton.setToolTipText(Dict.START.getString()); startButton.setEnabled(false); saveLogButton.setIcon(Pict.Actions.DOCUMENT_SAVE.get(ICON_SIZE)); saveLogButton.setEnabled(false); helpButton.setIcon(Pict.Actions.HELP_CONTENTS.get(ICON_SIZE)); helpButton.setToolTipText(Dict.HELP.getString()); DropTarget dropTarget = new DropTarget() { @Override public synchronized void drop(DropTargetDropEvent evt) { try { evt.acceptDrop(DnDConstants.ACTION_COPY); List<File> droppedFiles = (List<File>) evt.getTransferable() .getTransferData(DataFlavor.javaFileListFlavor); if (droppedFiles.get(0).isFile()) { openFile(droppedFiles.get(0)); } } catch (UnsupportedFlavorException | IOException ex) { } } }; scrollPane.setDropTarget(dropTarget); mTableModel = new GeotagTableModel(); table.setModel(mTableModel); mTableRowSorter = new TableRowSorter<>(mTableModel); table.setRowSorter(mTableRowSorter); TableColumnModel columnModel = table.getColumnModel(); NumericTableCellRenderer cooNumericTableCellRenderer = new NumericTableCellRenderer(Double.class, 6); NumericTableCellRenderer altNumericTableCellRenderer = new NumericTableCellRenderer(Double.class, 4); columnModel.getColumn(GeotagTableModel.COLUMN_LATITUDE).setCellRenderer(cooNumericTableCellRenderer); columnModel.getColumn(GeotagTableModel.COLUMN_LONGITUDE).setCellRenderer(cooNumericTableCellRenderer); columnModel.getColumn(GeotagTableModel.COLUMN_ALTITUDE).setCellRenderer(altNumericTableCellRenderer); columnModel.getColumn(GeotagTableModel.COLUMN_NAME).setPreferredWidth(200); columnModel.getColumn(GeotagTableModel.COLUMN_LATITUDE).setPreferredWidth(100); columnModel.getColumn(GeotagTableModel.COLUMN_LONGITUDE).setPreferredWidth(100); columnModel.getColumn(GeotagTableModel.COLUMN_ALTITUDE).setPreferredWidth(50); } /** * 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. */ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { toolBar = new javax.swing.JToolBar(); openButton = new javax.swing.JButton(); editToggleButton = new javax.swing.JToggleButton(); saveLogButton = new javax.swing.JButton(); closeButton = new javax.swing.JButton(); startButton = new javax.swing.JButton(); jSeparator1 = new javax.swing.JToolBar.Separator(); helpButton = new javax.swing.JButton(); scrollPane = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); toolBar.setFloatable(false); toolBar.setRollover(true); openButton.setToolTipText(Dict.OPEN.getString()); openButton.setFocusable(false); openButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); openButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); openButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { openButtonActionPerformed(evt); } }); toolBar.add(openButton); editToggleButton.setToolTipText(Dict.EDIT.getString()); editToggleButton.setEnabled(false); editToggleButton.setFocusable(false); editToggleButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); editToggleButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); editToggleButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { editToggleButtonActionPerformed(evt); } }); toolBar.add(editToggleButton); saveLogButton.setToolTipText(org.openide.util.NbBundle.getMessage(GeotaggerTopComponent.class, "GeotaggerTopComponent.saveLogButton.toolTipText")); // NOI18N saveLogButton.setFocusable(false); saveLogButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); saveLogButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); saveLogButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveLogButtonActionPerformed(evt); } }); toolBar.add(saveLogButton); closeButton.setToolTipText(Dict.CLOSE.getString()); closeButton.setFocusable(false); closeButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); closeButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); closeButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { closeButtonActionPerformed(evt); } }); toolBar.add(closeButton); startButton.setFocusable(false); startButton.setHorizontalAlignment(javax.swing.SwingConstants.LEADING); startButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { startButtonActionPerformed(evt); } }); toolBar.add(startButton); toolBar.add(jSeparator1); helpButton.setFocusable(false); helpButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); helpButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); helpButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { helpButtonActionPerformed(evt); } }); toolBar.add(helpButton); scrollPane.setViewportView(table); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(toolBar, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)); layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(toolBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE))); }// </editor-fold>//GEN-END:initComponents private void openFile(File file) { mSource = file; startButton.setEnabled(false); closeButton.setEnabled(false); editToggleButton.setSelected(false); editToggleButton.setEnabled(false); mTableModel.clear(); logClear(); new Thread(() -> { try { //Try open the file as pxy, if no valid pxy point, try open it as csv. openFilePxy(file); if (mTableModel.getRowCount() == 0) { openFileCsv(file); } if (mTableModel.getRowCount() > 0) { startButton.setEnabled(true); closeButton.setEnabled(true); editToggleButton.setEnabled(true); } else { } } catch (IOException ex) { Exceptions.printStackTrace(ex); } }).start(); } private void openFileCsv(File file) throws IOException { List<String> lines = FileUtils.readLines(file); lines.stream().forEach((line) -> { String[] elements = StringUtils.splitPreserveAllTokens(line, ";"); if (elements.length < 3 || elements[0].isEmpty() || elements[1].isEmpty() || elements[2].isEmpty()) { logAppend(String.format(" - %s: %s", mBundle.getString("invalidGeotag"), line)); } else { String name = elements[GeotagTableModel.COLUMN_NAME]; double latitude = NumberUtils.toDouble(elements[GeotagTableModel.COLUMN_LATITUDE]); double longitude = NumberUtils.toDouble(elements[GeotagTableModel.COLUMN_LONGITUDE]); double altitude = 0; if (elements.length > GeotagTableModel.COLUMN_ALTITUDE) { altitude = NumberUtils.toDouble(elements[GeotagTableModel.COLUMN_ALTITUDE]); } Geotag geotag = new Geotag(name, latitude, longitude, altitude); mTableModel.addRow(geotag); } }); } private void openFilePxy(File file) throws IOException { Pxy pxy = new Pxy(); try { pxy.read(file); } catch (MalformedInputException | NumberFormatException | StringIndexOutOfBoundsException e) { return; } pxy.getPoints().stream().forEach((point) -> { Geotag geotag = new Geotag(point.getPointId(), point.getX(), point.getY(), point.getZ()); mTableModel.addRow(geotag); }); } private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed table.setEnabled(false); Operation operation = new Operation(this, mTableModel.getDataVector()); operation.start(); }//GEN-LAST:event_startButtonActionPerformed private void saveLogButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveLogButtonActionPerformed }//GEN-LAST:event_saveLogButtonActionPerformed private void helpButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_helpButtonActionPerformed displayHelp("se.trixon.toolbox.geotagger.about"); }//GEN-LAST:event_helpButtonActionPerformed private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed FileNameExtensionFilter filter = new FileNameExtensionFilter( Dict.COORDINATE_FILE.getString() + " (*.csv, *.pxy)", "csv", "pxy", "CSV", "PXY"); SimpleDialog.clearFilters(); SimpleDialog.addFilter(filter); SimpleDialog.setFilter(filter); SimpleDialog.setParent(this); if (mSource != null) { SimpleDialog.setPath(mSource.getParentFile()); } if (SimpleDialog.openFile()) { openFile(SimpleDialog.getPath()); } }//GEN-LAST:event_openButtonActionPerformed private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed mTableModel.clear(); closeButton.setEnabled(false); startButton.setEnabled(false); editToggleButton.setEnabled(false); editToggleButton.setSelected(false); }//GEN-LAST:event_closeButtonActionPerformed private void editToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editToggleButtonActionPerformed mTableModel.setEditable(editToggleButton.isSelected()); }//GEN-LAST:event_editToggleButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton closeButton; private javax.swing.JToggleButton editToggleButton; private javax.swing.JButton helpButton; private javax.swing.JToolBar.Separator jSeparator1; private javax.swing.JButton openButton; private javax.swing.JButton saveLogButton; private javax.swing.JScrollPane scrollPane; private javax.swing.JButton startButton; private javax.swing.JTable table; private javax.swing.JToolBar toolBar; // End of variables declaration//GEN-END:variables @Override public void componentOpened() { } @Override public void componentClosed() { } void writeProperties(java.util.Properties p) { p.setProperty("version", "1.0"); } void readProperties(java.util.Properties p) { String version = p.getProperty("version"); } }