/* * This file is part of jHaushalt. * jHaushalt is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * jHaushalt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with jHaushalt; if not, see <http://www.gnu.org/licenses/>. * (C)opyright 2002-2010 Dr. Lars H. Hahn */ package haushalt.gui; import haushalt.auswertung.CsvHandler; import haushalt.auswertung.DlgContainerAuswertung; import haushalt.auswertung.FarbPaletten; import haushalt.auswertung.domain.ColumnModelProperties; import haushalt.auswertung.domain.HaushaltProperties; import haushalt.auswertung.domain.HaushaltPropertiesException; import haushalt.auswertung.domain.HaushaltDefinitionLoader; import haushalt.daten.AbstractBuchung; import haushalt.daten.Datenbasis; import haushalt.daten.Datenbasis.QuickenImportException; import haushalt.daten.Datum; import haushalt.daten.EinzelKategorie; import haushalt.daten.Euro; import haushalt.daten.ExtendedDatabase; import haushalt.daten.SplitBuchung; import haushalt.daten.StandardBuchung; import haushalt.daten.Umbuchung; import haushalt.gui.dialoge.DlgAutoBuchung; import haushalt.gui.dialoge.DlgBereinigen; import haushalt.gui.dialoge.DlgEinrichtung; import haushalt.gui.dialoge.DlgHilfe; import haushalt.gui.dialoge.DlgImport; import haushalt.gui.dialoge.DlgInfo; import haushalt.gui.dialoge.DlgKategorienBearbeiten; import haushalt.gui.dialoge.DlgOptionen; import haushalt.gui.dialoge.DlgRegisterBearbeiten; import haushalt.gui.dialoge.DlgSplitBuchung; import haushalt.gui.dialoge.DlgSuchenErsetzen; import haushalt.gui.generischerdialog.DatumGDP; import haushalt.gui.generischerdialog.EineKategorieGDP; import haushalt.gui.generischerdialog.EuroGDP; import haushalt.gui.generischerdialog.GenerischerDialog; import haushalt.gui.generischerdialog.RegisterGDP; import haushalt.gui.generischerdialog.TextGDP; import haushalt.gui.mac.MacAdapter; import haushalt.service.data.DatabaseFileLoaderImpl; import haushalt.service.data.DatabaseService; import haushalt.service.data.DatabaseServiceImpl; import haushalt.service.data.DatabaseServiceException; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Point; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.print.PrinterException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.Field; import java.net.URL; import java.net.URLClassLoader; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Locale; import java.util.logging.Logger; import javax.swing.DefaultCellEditor; import javax.swing.ImageIcon; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.ListSelectionModel; import javax.swing.ScrollPaneConstants; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.filechooser.FileFilter; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableColumnModel; import javax.swing.table.TableColumnModel; public class Haushalt implements KeyListener, ListSelectionListener { private static final Logger LOGGER = Logger.getLogger(Haushalt.class.getName()); private static final TextResource RES = TextResource.get(); private HaushaltProperties haushaltDefinition; private JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.BOTTOM); private TableColumnModel columnModel = null; private final GemerkteBuchungenGlassPane glassPane = new GemerkteBuchungenGlassPane(); private DlgOptionen dlgOptionen; private DlgSuchenErsetzen dlgSuchenErsetzen; private Datenbasis db; private DlgContainerAuswertung containerAuswertung; private ActionHandler actionHandler; private MainWindow mainWindow; private final FileFilter fileFilter = new JHaushaltFileFilter(); // FIXME Dependency Injection private DatabaseService databaseService; public Haushalt(final String dateiname) { this.actionHandler = new ActionHandler(this); final DatabaseServiceImpl internalDbService = new DatabaseServiceImpl(); internalDbService.setDatabaseFileLoader(new DatabaseFileLoaderImpl()); databaseService = internalDbService; // Properties laden try { haushaltDefinition = HaushaltDefinitionLoader.getHaushaltDefinition(); } catch (final HaushaltPropertiesException e) { showDialogToCreateJHHFile(); } mainWindow = new MainWindow( haushaltDefinition.getMainWindowProperties(), tabbedPane, actionHandler, glassPane); mainWindow.defineMainWindow(); setLocaleAndFrameLocale(); setLookAndFeelDependingOnSystem(); this.dlgSuchenErsetzen = new DlgSuchenErsetzen(this); defineMenuBar(); loadOrCreateDatabaseFile(dateiname); defineOptionsDialog(); oberflaecheAnpassen(); // hier werden auch andere Optionen gesetzt // some smaller improvements for apple-users if (isMacOSX()) { MacAdapter.macStyle(this); } } public JFrame getFrame() { return mainWindow.getFrame(); } private void defineOptionsDialog() { this.dlgOptionen = new DlgOptionen(this, haushaltDefinition.getDlgOptionProperties()); } private void loadOrCreateDatabaseFile(final String dateiname) { // Letzte Datei laden oder neu initialisieren // In jedem Fall wird die Datenbasis erzeugt. final String fileToLoad = (dateiname != null)? dateiname: (haushaltDefinition.getJhhFileName() != null)? haushaltDefinition.getJhhFileName() : null; if (fileToLoad != null) { loadDatabase(new File(fileToLoad)); } else { neu(); } } private void defineMenuBar() { mainWindow.getFrame().setJMenuBar(this.actionHandler.erzeugeMenuBar()); } private void setLookAndFeelDependingOnSystem() { final String systemClassName = UIManager.getSystemLookAndFeelClassName(); try { UIManager.setLookAndFeel(systemClassName); } catch (final Exception e) { LOGGER.warning(e.getMessage()); } } private void setLocaleAndFrameLocale() { // Das Neusetzen der Locale geht leider nicht an einer zentralen Stelle RES.setLocale(haushaltDefinition.getUserOrSystemLocale()); Locale.setDefault(RES.getLocale()); mainWindow.getFrame().setLocale(RES.getLocale()); } private void showDialogToCreateJHHFile() { final DlgEinrichtung einrichten = new DlgEinrichtung( mainWindow.getFrame(), haushaltDefinition.createJHHDialogProperties()); einrichten.pack(); einrichten.setVisible(true); } /** * Liefert das Arbeitsverzeichnis. * * @return Arbeitsverzeichnis */ public String getOrdner() { return haushaltDefinition.getJhhFolder(); } // -- Einstellungen // --------------------------------------------------------- /** * Übernimmt die optionalen Einstellungen des Benutzters. * */ private void oberflaecheAnpassen() { setTabPlacement(haushaltDefinition.getTabPlacement()); for (int i = 0; i < tabbedPane.getTabCount(); i++) { final JScrollPane scrollPane = (JScrollPane) tabbedPane.getComponent(i); final JTable table = (JTable) scrollPane.getViewport().getView(); table.setSelectionBackground(getFarbeSelektion()); table.setGridColor(getFarbeGitter()); } db.setStartDatum(haushaltDefinition.getTransactionStartDate()); DeleteableTextField.setDeltaste(haushaltDefinition.setDeleteKeyCode()); FarbPaletten.setCustomColor(haushaltDefinition.getCustomColorCodes()); } public Color getFarbeSelektion() { return haushaltDefinition.getSelectionColor(); } public Color getFarbeGitter() { return haushaltDefinition.getGridColor(); } public Color getFarbeZukunft() { return haushaltDefinition.getFarbeZukunft(); } public String getFontname() { return haushaltDefinition.getFontName(); } public int getFontgroesse() { return haushaltDefinition.getFontSize(); } /** * Lädt Bilder aus dem Verzeichnis <code>res/</code>. * * @param dateiname * Dateiname des Bildes (ohne Pfad) */ public ImageIcon bildLaden(final String dateiname) { final URLClassLoader urlLoader = (URLClassLoader) getClass().getClassLoader(); final URL fileLoc = urlLoader.findResource("res/" + dateiname); return new ImageIcon(fileLoc); } /** * Setzt den Ort der Register-Reiter. * * @param tabPlacement * "TOP", "BOTTOM", "LEFT" oder "RIGHT" */ private void setTabPlacement(final String tabPlacement) { int tp = SwingConstants.BOTTOM; final Class<?> c = SwingConstants.class; try { final Field field = c.getField(tabPlacement); tp = field.getInt(Integer.valueOf(0)); } catch (final NoSuchFieldException e) { LOGGER.warning(e.getMessage()); } catch (final IllegalAccessException e) { LOGGER.warning(e.getMessage()); } tabbedPane.setTabPlacement(tp); } // -- Register-Tabellen // ------------------------------------------------------ /** * Wandelt alle Register in Tabellen um und zeigt sie so an. */ private void zeigeAlleRegisterTabs() { final String[] register = db.getRegisterNamen(); for (int i = 0; i < register.length; i++) { zeigeRegisterTab(register[i]); } } /** * Wandelt ein Register in eine Tabelle um und zeigt sie so an. * * @param regname * Name des Registers * @return Nummer des Registers */ public int zeigeRegisterTab(final String regname) { final int tabNr = tabbedPane.indexOfTab(regname); final ColumnModelProperties columnModelProperties = haushaltDefinition.getColumnModelProperties(); // int tabNr = getRegisterTabNr(""+tableModel); if (tabNr > -1) { // Register wird schon angezeigt, wahrscheinlich wurde es verändert: registerVeraendert(tabNr); return tabNr; } final RegisterTableModel tableModel = new RegisterTableModel(this, db, regname); JTable table; if (columnModel == null) { // Das ColumnModel wird von der ersten erzeugten Tabelle genommen // und initialisiert. Alle Tabellen erhalten so die gleichen Spalten-Breiten. table = new JTable(tableModel); columnModel = table.getColumnModel(); if (columnModelProperties.doesWidthExistForColumnNumber(0)) { for (int j = 0; j < columnModel.getColumnCount(); j++) { final int breite = columnModelProperties.getRegisterWidthForColumnNumber(j); columnModel.getColumn(j).setPreferredWidth(breite); } } } else { table = new JTable(tableModel, columnModel); } table.setSurrendersFocusOnKeystroke(true); table.getSelectionModel().addListSelectionListener(this); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setSelectionBackground(getFarbeSelektion()); table.setGridColor(getFarbeGitter()); table.setComponentPopupMenu(actionHandler.getPopupMenu()); // Cell-Editoren erzeugen table.setDefaultEditor(Datum.class, new DefaultCellEditor(new DatumField())); final DeleteableTextField textField = new DeleteableTextField(); textField.addKeyListener(this); final DefaultCellEditor cellEditor = new DefaultCellEditor(textField); table.setDefaultEditor(String.class, cellEditor); table.setDefaultEditor(Object.class, new KategorieCellEditor(this, db)); table.setDefaultEditor(Euro.class, new DefaultCellEditor(new EuroField())); // Cell-Renderer erzeugen table.setDefaultRenderer(Datum.class, new DatumRenderer(haushaltDefinition.getDateRendererProperties())); table.setDefaultRenderer(String.class, new DefaultTableCellRenderer()); table.setDefaultRenderer(Object.class, new KategorieRenderer()); table.setDefaultRenderer(Euro.class, new EuroRenderer()); final JScrollPane scrollPane = new JScrollPane(table); scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); tabbedPane.add(scrollPane, "" + tableModel); table.setRowSelectionInterval(table.getRowCount() - 1, table.getRowCount() - 1); final JScrollBar scrollBar = scrollPane.getVerticalScrollBar(); // JavaBug: Hier ist der maxValue noch 100 ... scrollBar.setValue(100); // Hier hat MaxValue den tatsaechlichen Wert ... scrollBar.setValue(scrollBar.getMaximum()); if (tabbedPane.getTabCount() == 1) { mainWindow.getFrame().getContentPane().add(tabbedPane, BorderLayout.CENTER); mainWindow.getFrame().validate(); } mainWindow.getFrame().repaint(); return tabbedPane.getTabCount() - 1; } /** * Nennt den Tab eines Registers um. * * @param alterName * alter Name des Registers * @param neuerName * neuer Name des Registers */ public void renameRegisterTab(final String alterName, final String neuerName) { final int idx = tabbedPane.indexOfTab(alterName); tabbedPane.setTitleAt(idx, neuerName); final JScrollPane scrollPane = (JScrollPane) tabbedPane.getComponentAt(idx); final JTable table = (JTable) scrollPane.getViewport().getView(); final RegisterTableModel tableModel = (RegisterTableModel) table.getModel(); tableModel.setRegisterName(neuerName); } /** * Erhöht den Index des Register-Tabs um eins. * * @param regname * Registername */ public void bewegeRegisterNachOben(final String regname) { final int idx = tabbedPane.indexOfTab(regname); final JScrollPane scrollPane = (JScrollPane) tabbedPane.getComponentAt(idx); tabbedPane.removeTabAt(idx); tabbedPane.insertTab(regname, null, scrollPane, null, idx + 1); } /** * Erniedrigt den Index des Register-Tabs um eins. * * @param regname * Registername */ public void bewegeRegisterNachUnten(final String regname) { final int idx = tabbedPane.indexOfTab(regname); final JScrollPane scrollPane = (JScrollPane) tabbedPane.getComponentAt(idx); tabbedPane.removeTabAt(idx); tabbedPane.insertTab(regname, null, scrollPane, null, idx - 1); } /** * Löscht die Tabelle zu einem Register. Falls keine Tabelle mehr vorhanden * ist, * wird wieder das Hintergrundbild angezeigt. * * @param regname * Name des Registers */ private void entferneRegisterTab(final String regname) { for (int i = 0; i < tabbedPane.getTabCount(); i++) { if (regname.equals(tabbedPane.getTitleAt(i))) { final JScrollPane scrollPane = (JScrollPane) tabbedPane.getComponentAt(i); final JTable table = (JTable) scrollPane.getViewport().getView(); // Die Register teilen sich ein ColumnModel, bevor ein Register // gelöscht wird // muss daher das ColumnModel neu gesetzt werden. table.setColumnModel(new DefaultTableColumnModel()); tabbedPane.removeTabAt(i); } } if (tabbedPane.getTabCount() == 0) { // Wenn das letzte Register entfernt wurde, wird auch die TabbedPane // entfernt. // Dies ist ein Relikt aus der Zeit als noch ein Hintergrund // angezeigt wurde columnModel = null; mainWindow.getFrame().getContentPane().remove(tabbedPane); mainWindow.getFrame().validate(); } mainWindow.getFrame().repaint(); } private void entferneAlleRegisterTabs() { final Container contentPane = mainWindow.getFrame().getContentPane(); tabbedPane.removeAll(); contentPane.remove(tabbedPane); columnModel = null; mainWindow.getFrame().validate(); mainWindow.getFrame().repaint(); } /** * Teilt mit, dass die Daten des Registers verändert wurden * * @param name * Name des Registers */ public void registerVeraendert(final String name) { registerVeraendert(tabbedPane.indexOfTab(name)); } private void registerVeraendert(final int nr) { final JScrollPane scrollPane = (JScrollPane) tabbedPane.getComponentAt(nr); final JTable table = (JTable) scrollPane.getViewport().getView(); final RegisterTableModel tableModel = (RegisterTableModel) table.getModel(); tableModel.fireTableDataChanged(); } public void alleRegisterVeraendert() { for (int i = 0; i < tabbedPane.getTabCount(); i++) { registerVeraendert(i); } } /** * Wählt eine bestimmte Buchung in einer der Register-Tabellen aus. * * @param regname * Name des Registers * @param buchungIndex * Zeile der Buchung */ public void selektiereBuchung(final String regname, int buchungIndex) { final int tabIndex = tabbedPane.indexOfTab(regname); if (tabIndex > -1) { tabbedPane.setSelectedIndex(tabIndex); final JScrollPane scrollPane = (JScrollPane) tabbedPane.getComponentAt(tabIndex); final JViewport viewport = scrollPane.getViewport(); final JTable table = (JTable) viewport.getComponent(0); if (buchungIndex >= table.getRowCount()) { buchungIndex = table.getRowCount() - 1; } table.setRowSelectionInterval(buchungIndex, buchungIndex); table.scrollRectToVisible(table.getCellRect(buchungIndex, 0, true)); } else { mainWindow.setStatus("-E- " + RES.getString("status_register_not_found1") + " " + regname + " " + RES.getString("status_register_not_found2")); } } // -- Gemerkte Buchungen // ----------------------------------------------------- /** * Setzt die Koordinaten an denen die gemerkte Buchung erscheinen soll. * Die Koordinaten werden in Abhängigkeit von dem TextField gesetzt in dem * der Buchungstext eingegeben wird. * * @param comp * Component = JTextField */ public void setzteKoordinatenGemerkteBuchung(final Component comp) { final Point xy = SwingUtilities.convertPoint(comp.getParent(), comp.getX(), comp.getY(), glassPane); glassPane.setTextKoordinaten(xy); } public boolean gemerkteBuchungen() { return haushaltDefinition.haveExistingTransactions(); } /** * Zeigt eine zuvor gemerkte Buchung an. * * @param prefix * Anfang des Buchungstextes */ public void zeigeGemerkteBuchung(final String prefix) { if (gemerkteBuchungen()) { final AbstractBuchung buchung = db.findeGemerkteBuchung(prefix); if (buchung != null) { final String text = buchung.getText() + " / " + buchung.getKategorie() + " / " + buchung.getWert(); glassPane.setText(text); glassPane.setVisible(true); } else { glassPane.setVisible(false); } } } /** * Überprüft, ob schon ein Register angelegt wurde * * @return <code>false</code> mindestens ein Register vorhanden */ private boolean keinRegisterVorhanden() { if (tabbedPane.getTabCount() == 0) { final int n = JOptionPane.showConfirmDialog( mainWindow.getFrame(), RES.getString("message_no_register"), RES.getString("warning"), JOptionPane.YES_NO_OPTION); if (n == JOptionPane.OK_OPTION) { registerBearbeiten(); } return true; } return false; } // == Menü: Datei // ============================================================ /** * Überprüft, ob die Applikationsdaten geändert wurden. Wird von neu() und * beenden() aufgerufen. * * @return <code>true</code> - Applikation wurde geändert, <code>false</code> - Daten sind gespeichert */ private boolean areAllFilesInASavedStatus() { if (db == null) { return true; // FIXME well, seems to be the most reasonable one } if (areThereUnsavedChanges()) { final int n = JOptionPane.showConfirmDialog(mainWindow.getFrame(), RES.getString("message_data_changed")); switch (n) { case JOptionPane.CANCEL_OPTION: return false; case JOptionPane.NO_OPTION: return true; case JOptionPane.OK_OPTION: speichern(); return !areThereUnsavedChanges(); default: break; } } return true; } private boolean areThereUnsavedChanges() { return (db.isGeaendert() || containerAuswertung.isGeaendert()); } public void neu() { if (areAllFilesInASavedStatus()) { haushaltDefinition.setJhhFileName(""); entferneAlleRegisterTabs(); db = new Datenbasis(); showDialogEvaluation(db); mainWindow.setCopyrightText(); final String name = db.erzeugeRegister(RES.getString("default_register_name")); zeigeRegisterTab(name); db.addUmbuchung(new Datum(), RES.getString("opening_balance"), name, name, Euro.NULL_EURO); } } private void loadDatabase(final File datei) { entferneAlleRegisterTabs(); reallyLoadDatabase(datei); doAutomatedTransactions(); zeigeAlleRegisterTabs(); final String dateiname = datei.getPath() + ".jha"; showDialogEvaluation(db); containerAuswertung.laden(dateiname); } private void showDialogEvaluation(final Datenbasis db) { containerAuswertung = new DlgContainerAuswertung(this, db); containerAuswertung.setPreferredSize(getPreferredEvaluationDimension()); } private void doAutomatedTransactions() { final int anzahl = db.ausfuehrenAutoBuchungen(new Datum()); if (anzahl > 0) { mainWindow.setStatus(RES.getString("executed_automatic_bookings1") + " " + anzahl + " " + RES.getString("executed_automatic_bookings2")); } } private void reallyLoadDatabase(final File datei) { ExtendedDatabase loadedDatabase = null; try { loadedDatabase = databaseService.loadDatabase(datei); } catch (final FileNotFoundException e) { handleJhhFileException("-E- " + datei.getPath() + " " + RES.getString("status_not_found")); } catch (final DatabaseServiceException e) { handleJhhFileException("-E- " + RES.getString("status_load_error") + ": " + datei.getPath()); } if (Datenbasis.givenVersionEqualsDatabaseVersion(loadedDatabase.getVersionId()) || hasUserConfirmedWarningMessage(loadedDatabase.getVersionId())) { this.db = loadedDatabase.getDataBase(); } } private boolean hasUserConfirmedWarningMessage(final String versionInfo) { final String warningTitle = RES.getString("warning"); final String warningMessage = getWarningMessage(versionInfo); final int confirmationAnswer = JOptionPane.showConfirmDialog(null, warningMessage, warningTitle, JOptionPane.YES_NO_OPTION); return confirmationAnswer == JOptionPane.YES_OPTION; } private String getWarningMessage(final String versionInfo) { final String warningMessage = RES.getString("message_old_version1") + " " + versionInfo + " " + RES.getString("message_old_version2") + Datenbasis.VERSION_DATENBASIS + RES.getString("message_old_version3"); return warningMessage; } private Dimension getPreferredEvaluationDimension() { final int auswertungBreite = haushaltDefinition.getEvaluationWidth(); final int auswertungHoehe = haushaltDefinition.getEvaluationHeight(); return new Dimension(auswertungBreite, auswertungHoehe); } public void laden() { if (areAllFilesInASavedStatus()) { final JFileChooser dateidialog = new JFileChooser(); dateidialog.setFileFilter(fileFilter); dateidialog.setCurrentDirectory(new File(haushaltDefinition.getJhhFolder())); if (dateidialog.showOpenDialog(mainWindow.getFrame()) == JFileChooser.APPROVE_OPTION) { loadDatabase(dateidialog.getSelectedFile()); } } } private void handleJhhFileException(final String message) { mainWindow.setStatus(message); haushaltDefinition.setJhhFileName(null); } public void speichern() { final String dateiname = haushaltDefinition.getJhhFileName(); if (dateiname == null) { speichernUnter(); } else { speichern(new File(dateiname)); } } private void speichern(File datei) { if (!datei.getName().toLowerCase().endsWith(".jhh")) { final String name = datei.getAbsolutePath() + ".jhh"; datei = new File(name); } try { databaseService.saveDbFile(db); haushaltDefinition.setJhhFileName(datei.getPath()); mainWindow.setStatus(datei.getPath() + " " + RES.getString("status_saved") + "."); } catch (final FileNotFoundException e1) { mainWindow.setStatus("-E- " + datei.getPath() + " " + RES.getString("status_not_found")); } catch (final DatabaseServiceException e) { mainWindow.setStatus("-E- " + RES.getString("status_write_error") + ": " + datei.getPath()); } // Speichern der Auswertungen containerAuswertung.speichern(datei.getPath() + ".jha"); } public void speichernUnter() { final JFileChooser dateidialog = new JFileChooser(); dateidialog.setFileFilter(fileFilter); dateidialog.setCurrentDirectory(new File(haushaltDefinition.getJhhFolder())); if (dateidialog.showSaveDialog(mainWindow.getFrame()) == JFileChooser.APPROVE_OPTION) { final File selectedFile = dateidialog.getSelectedFile(); db.setFileName(selectedFile.getAbsolutePath()); speichern(selectedFile); } } public void beenden() { if (areAllFilesInASavedStatus()) { final Dimension dimension = tabbedPane.getSize(); haushaltDefinition.setProperty("jhh.register.breite", "" + dimension.width); if (dimension.height > 100) { haushaltDefinition.setProperty("jhh.register.hoehe", "" + dimension.height); } else { haushaltDefinition.setProperty("jhh.register.hoehe", "100"); } if (columnModel != null) { for (int i = 0; i < columnModel.getColumnCount(); i++) { haushaltDefinition.setProperty("jhh.register.spalte" + i, "" + columnModel.getColumn(i).getWidth()); } } try { haushaltDefinition.save(); } catch (final HaushaltPropertiesException e) { LOGGER.info("Could not save haushalt definition."); LOGGER.warning(e.getMessage()); } System.exit(0); } } // === Menü: Bearbeiten // ====================================================== public void suchen() { if (keinRegisterVorhanden()) { return; } dlgSuchenErsetzen.showDialog(db); } public void neueBuchungErstellen() { final int registerIndex = tabbedPane.getSelectedIndex(); final String regname = tabbedPane.getTitleAt(registerIndex); db.addStandardBuchung(regname, new StandardBuchung()); final JScrollPane scrollPane = (JScrollPane) tabbedPane.getSelectedComponent(); final JTable table = (JTable) scrollPane.getViewport().getView(); final RegisterTableModel tableModel = (RegisterTableModel) table.getModel(); final int buchungIndex = table.getRowCount(); tableModel.fireTableRowsInserted(buchungIndex, buchungIndex); } public void umbuchen() { if (keinRegisterVorhanden()) { return; } final int registerIndex = tabbedPane.getSelectedIndex(); final String regname = tabbedPane.getTitleAt(registerIndex); final GenerischerDialog dlg = new GenerischerDialog(RES.getString("create_rebooking"), mainWindow.getFrame()); final DatumGDP pane1 = new DatumGDP(RES.getString("insert_date") + ":", new Datum()); dlg.addPane(pane1); final TextGDP pane2 = new TextGDP(RES.getString("insert_posting_text") + ":", RES.getString("default_posting_text")); dlg.addPane(pane2); final RegisterGDP pane3 = new RegisterGDP(RES.getString("select_source_register") + ":", db, regname); dlg.addPane(pane3); final RegisterGDP pane4 = new RegisterGDP(RES.getString("select_destination_register") + ":", db, regname); dlg.addPane(pane4); final EuroGDP pane5 = new EuroGDP(RES.getString("insert_amount") + ":", new Euro()); dlg.addPane(pane5); if (dlg.showDialog()) { final Datum datum = (Datum) pane1.getRefreshedWert(); final String text = "" + pane2.getRefreshedWert(); final String quelle = "" + pane3.getRefreshedWert(); final String ziel = "" + pane4.getRefreshedWert(); final Euro betrag = (Euro) pane5.getRefreshedWert(); db.addUmbuchung(datum, text, quelle, ziel, betrag); registerVeraendert(quelle); registerVeraendert(ziel); } } public void loeschen() { if (keinRegisterVorhanden()) { return; } final int registerIndex = tabbedPane.getSelectedIndex(); final JScrollPane scrollPane = (JScrollPane) tabbedPane.getSelectedComponent(); final String regname = tabbedPane.getTitleAt(registerIndex); final JTable table = (JTable) scrollPane.getViewport().getView(); final int buchungIndex = table.getSelectedRow(); if (buchungIndex == -1) { JOptionPane.showMessageDialog(mainWindow.getFrame(), RES.getString("message_no_row_selected")); return; } if (buchungIndex == db.getAnzahlBuchungen(regname)) { JOptionPane.showMessageDialog(mainWindow.getFrame(), RES.getString("message_row_can_not_be_deleted")); return; } db.entferneBuchung(regname, buchungIndex); final RegisterTableModel tableModel = (RegisterTableModel) table.getModel(); tableModel.fireTableRowsDeleted(buchungIndex, buchungIndex); if (table.getCellEditor() != null) { table.getCellEditor().cancelCellEditing(); } table.requestFocus(); table.setRowSelectionInterval(buchungIndex, buchungIndex); mainWindow.setStatus(RES.getString("status_posting_deleted1") + " " + (buchungIndex + 1) + " " + RES.getString("status_posting_deleted2") + " " + regname + " " + RES.getString("status_posting_deleted3")); } public void splitten() { if (keinRegisterVorhanden()) { return; } final int registerIndex = tabbedPane.getSelectedIndex(); final JScrollPane scrollPane = (JScrollPane) tabbedPane.getSelectedComponent(); final String regname = tabbedPane.getTitleAt(registerIndex); final JTable table = (JTable) scrollPane.getViewport().getView(); final int buchungIndex = table.getSelectedRow(); if (buchungIndex == -1) { JOptionPane.showMessageDialog(mainWindow.getFrame(), RES.getString("message_no_row_selected")); return; } final AbstractBuchung buchung = db.getBuchung(regname, buchungIndex); if (buchung.getClass() == Umbuchung.class) { JOptionPane.showMessageDialog(mainWindow.getFrame(), RES.getString("message_rebookings_can_not_be_split")); } else { SplitBuchung splitBuchung; if (buchung.getClass() == StandardBuchung.class) { splitBuchung = new SplitBuchung((StandardBuchung) buchung); } else { splitBuchung = (SplitBuchung) buchung; } final JDialog dlg = new DlgSplitBuchung(this, db, splitBuchung); dlg.pack(); dlg.setVisible(true); final int pos = db.ersetzeBuchung(regname, buchungIndex, splitBuchung.reduziere()); db.buchungMerken(splitBuchung.reduziere()); registerVeraendert(regname); selektiereBuchung(regname, pos); } if (table.getCellEditor() != null) { table.getCellEditor().cancelCellEditing(); } table.requestFocus(); } public void umwandeln() { if (keinRegisterVorhanden()) { return; } final int registerIndex = tabbedPane.getSelectedIndex(); final JScrollPane scrollPane = (JScrollPane) tabbedPane.getSelectedComponent(); final String regname = tabbedPane.getTitleAt(registerIndex); final JTable table = (JTable) scrollPane.getViewport().getView(); final int buchungIndex = table.getSelectedRow(); if (buchungIndex == -1) { JOptionPane.showMessageDialog(mainWindow.getFrame(), RES.getString("message_no_row_selected")); return; } if (buchungIndex == db.getAnzahlBuchungen(regname)) { JOptionPane.showMessageDialog(mainWindow.getFrame(), RES.getString("message_row_can_not_be_deleted")); return; } final AbstractBuchung buchung = db.getBuchung(regname, buchungIndex); if (buchung.getClass() == Umbuchung.class) { JOptionPane.showMessageDialog(mainWindow.getFrame(), RES.getString("message_posting_is_already_a_reposting")); return; } final GenerischerDialog dlg = new GenerischerDialog(RES.getString("convert"), mainWindow.getFrame()); final RegisterGDP pane = new RegisterGDP(RES.getString("select_destination_register") + ":", db, regname); dlg.addPane(pane); if (dlg.showDialog()) { final Datum datum = buchung.getDatum(); final String text = buchung.getText(); final String quelle = regname; final String ziel = "" + pane.getRefreshedWert(); final Euro betrag = Euro.NULL_EURO.sub(buchung.getWert()); db.entferneBuchung(regname, buchungIndex); db.addUmbuchung(datum, text, quelle, ziel, betrag); registerVeraendert(quelle); registerVeraendert(ziel); } } public void registerBearbeiten() { final DlgRegisterBearbeiten dlg = new DlgRegisterBearbeiten(this, db); dlg.showDialog(); } public void kategorienBearbeiten() { final DlgKategorienBearbeiten dlg = new DlgKategorienBearbeiten(this, db); dlg.showDialog(); alleRegisterVeraendert(); } public void alteBuchungenLoeschen() { final GenerischerDialog dlg = new GenerischerDialog(RES.getString("delete_old_bookings"), mainWindow.getFrame()); final DatumGDP pane = new DatumGDP(RES.getString("cutoff_date") + ":", new Datum()); pane.setPreferredSize(new Dimension(320, 60)); dlg.addPane(pane); if (dlg.showDialog()) { final Datum datum = (Datum) pane.getRefreshedWert(); db.entferneAlteBuchungen(datum); alleRegisterVeraendert(); mainWindow.setStatus(RES.getString("status_posting_deleted4") + " " + datum + " " + RES.getString("status_posting_deleted5")); } } public void kategorieErsetzen() { final GenerischerDialog dlg = new GenerischerDialog(RES.getString("replace_category"), mainWindow.getFrame()); final EineKategorieGDP pane1 = new EineKategorieGDP(RES.getString("current_category") + ":", db, null); dlg.addPane(pane1); final EineKategorieGDP pane2 = new EineKategorieGDP(RES.getString("new_category") + ":", db, null); dlg.addPane(pane2); if (dlg.showDialog()) { final EinzelKategorie alteKategorie = (EinzelKategorie) pane1.getRefreshedWert(); final EinzelKategorie neueKategorie = (EinzelKategorie) pane2.getRefreshedWert(); final int anzahl = db.ersetzeKategorie(alteKategorie, neueKategorie); mainWindow.setStatus("" + anzahl + " " + RES.getString("status_replaced_categories")); alleRegisterVeraendert(); } } public void kategorienBereinigen() { final JDialog dlg = new DlgBereinigen(this, db); dlg.pack(); dlg.setVisible(true); alleRegisterVeraendert(); } public void registerVereinigen() { if (keinRegisterVorhanden()) { return; } final int registerIndex = tabbedPane.getSelectedIndex(); final String regname = tabbedPane.getTitleAt(registerIndex); final GenerischerDialog dlg = new GenerischerDialog(RES.getString("join_register"), mainWindow.getFrame()); final RegisterGDP pane1 = new RegisterGDP(RES.getString("select_source_register") + ":", db, regname); pane1.setPreferredSize(new Dimension(330, 60)); dlg.addPane(pane1); final RegisterGDP pane2 = new RegisterGDP(RES.getString("select_destination_register") + ":", db, regname); pane2.setPreferredSize(new Dimension(330, 60)); dlg.addPane(pane2); if (dlg.showDialog()) { final String quelle = (String) pane1.getRefreshedWert(); final String ziel = (String) pane2.getRefreshedWert(); if (!quelle.equals(ziel)) { db.registerVereinigen(quelle, ziel); entferneRegisterTab(quelle); mainWindow.setStatus(RES.getString("status_register_deleted1") + " " + quelle + " " + RES.getString("status_register_deleted2")); registerVeraendert(ziel); } else { JOptionPane.showMessageDialog(mainWindow.getFrame(), RES.getString("message_registers_may_not_be_equal")); } } } // == Menü: Ausgabe // ========================================================== public void zeigeAuswertung() { if (keinRegisterVorhanden()) { return; } containerAuswertung.zeigeDialog(); final Dimension dimension = containerAuswertung.getSize(); haushaltDefinition.setProperty("jhh.auswertung.breite", "" + dimension.width); haushaltDefinition.setProperty("jhh.auswertung.hoehe", "" + dimension.height); containerAuswertung.setPreferredSize(dimension); } public void exportCSV() { if (keinRegisterVorhanden()) { return; } final ArrayList<String[]> buchungen = db.getBuchungen(); final CsvHandler handler = new CsvHandler(buchungen); handler.exportDlg(mainWindow.getFrame(), haushaltDefinition.getJhhFolder()); } public void drucken() { final int tabIndex = tabbedPane.getSelectedIndex(); if (tabIndex != -1) { final JScrollPane scrollPane = (JScrollPane) tabbedPane.getComponentAt(tabIndex); final JViewport viewport = scrollPane.getViewport(); final JTable table = (JTable) viewport.getComponent(0); final MessageFormat header = new MessageFormat(RES.getString("register") + ": " + tabbedPane.getTitleAt(tabIndex)); final MessageFormat footer = new MessageFormat(RES.getString("message_printed_with")); try { table.print(JTable.PrintMode.FIT_WIDTH, header, footer, true, null, true); } catch (final PrinterException e) { LOGGER.warning(e.getMessage()); } } } // == Menü: Extras // =========================================================== public void optionen() { dlgOptionen.showDialog(); oberflaecheAnpassen(); } public void autoBuchung() { if (keinRegisterVorhanden()) { return; } final DlgAutoBuchung dlg = new DlgAutoBuchung(this, db); dlg.zeigeDialog(); alleRegisterVeraendert(); } public void importCSV() { if (keinRegisterVorhanden()) { return; } final int registerIndex = tabbedPane.getSelectedIndex(); final String regname = tabbedPane.getTitleAt(registerIndex); final DlgImport spaltenZuordnung = new DlgImport(this); spaltenZuordnung.pack(); spaltenZuordnung.setVisible(true); final String[][] importTabelle = spaltenZuordnung.getImportTabelle(); if (importTabelle != null) { db.importBuchungen(regname, importTabelle); mainWindow.setStatus("" + importTabelle.length + " " + RES.getString("status_postings_imported")); registerVeraendert(registerIndex); } } public void importQuicken() { if (keinRegisterVorhanden()) { return; } final int registerIndex = tabbedPane.getSelectedIndex(); final String regname = tabbedPane.getTitleAt(registerIndex); final GenerischerDialog dlg = new GenerischerDialog(RES.getString("import_quicken"), mainWindow.getFrame()); final RegisterGDP pane = new RegisterGDP(RES.getString("select_register") + ":", db, regname); pane.setPreferredSize(new Dimension(250, 60)); dlg.addPane(pane); if (dlg.showDialog()) { final JFileChooser dateidialog = new JFileChooser(); dateidialog.setCurrentDirectory(new File(haushaltDefinition.getJhhFolder())); if (dateidialog.showOpenDialog(mainWindow.getFrame()) == JFileChooser.APPROVE_OPTION) { final File datei = dateidialog.getSelectedFile(); try { final FileInputStream in = new FileInputStream(datei); db.importQuickenRegister( in, (String) pane.getRefreshedWert(), haushaltDefinition.isDataImportInEuroCurrency()); in.close(); zeigeAlleRegisterTabs(); } catch (final FileNotFoundException e1) { LOGGER.warning("-E- " + datei.getPath() + " nicht gefunden!"); mainWindow.setStatus(e1.getMessage()); } catch (final IOException e2) { LOGGER.warning("-E- Fehler beim Importieren: " + datei.getPath()); mainWindow.setStatus(e2.getMessage()); } catch (final QuickenImportException e) { LOGGER.warning("-E- Fehler beim Importieren: " + datei.getPath()); mainWindow.setStatus(e.getMessage()); } } } } // == Menü: Hilfe // ============================================================ /** * Wird von Menü-Handler bei Auswahl von '<b>Hilfe/Inhalt</b>' aufgerufen. * Es wird standardmäßig die Datei "html/help.html" angezeigt. */ public void hilfeInhalt() { final DlgHilfe dlg = new DlgHilfe(mainWindow.getFrame()); dlg.pack(); dlg.setVisible(true); } /** * Wird von Menü-Handler bei Auswahl von '<b>Hilfe/Programm-Info</b>' * aufgerufen. */ public void programmInfo() { final DlgInfo dlg = new DlgInfo(mainWindow.getFrame()); dlg.pack(); dlg.setVisible(true); } // -- Methoden des Interface 'KeyListener' // ----------------------------------- public void keyReleased(final KeyEvent e) { if (e.getSource().getClass() == DeleteableTextField.class) { final DeleteableTextField textField = (DeleteableTextField) e.getSource(); setzteKoordinatenGemerkteBuchung(textField); zeigeGemerkteBuchung(textField.getText()); } } public void keyPressed(final KeyEvent e) { // nichts zu tun ! } public void keyTyped(final KeyEvent e) { // nichts zu tun ! } // -- Methoden des Interface 'ListSelectionListener' // ---------------------------- public void valueChanged(final ListSelectionEvent e) { glassPane.setVisible(false); } public static boolean isMacOSX() { final String osName = System.getProperty("os.name"); return osName.startsWith("Mac OS X"); } // -- MAIN // ------------------------------------------------------------------- public static void main(final String[] args) { final String version = System.getProperty("java.specification.version"); if (version.compareTo("1.5") < 0) { JOptionPane.showMessageDialog( null, RES.getString("message_wrong_java_version1") + " " + version + " " + RES.getString("message_wrong_java_version2")); System.exit(0); } String dateiname = null; if ((args.length > 0) && (!args[0].equals(""))) { dateiname = args[0]; } // small 'hack' for Apple-users if (isMacOSX()) { System.setProperty("apple.laf.useScreenMenuBar", "true"); System.setProperty("com.apple.mrj.application.apple.menu.about.name", "jHaushalt"); } final Haushalt haushalt = new Haushalt(dateiname); SwingUtilities.invokeLater(new Runnable() { public void run() { final JFrame mainFrame = haushalt.getFrame(); mainFrame.pack(); // Frame mittig im Bildschirm platzieren: mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); } }); } }