List of usage examples for javax.swing.table DefaultTableModel getValueAt
public Object getValueAt(int row, int column)
row
and column
. From source file:com.mirth.connect.client.ui.ChannelSetup.java
private void saveChannelTags() { currentChannel.getProperties().getTags().clear(); DefaultTableModel model = (DefaultTableModel) tagTable.getModel(); int rowCount = model.getRowCount(); for (int i = 0; i < rowCount; i++) { currentChannel.getProperties().getTags().add((String) model.getValueAt(i, 0)); }// w w w .ja va 2 s .co m }
From source file:com.mirth.connect.client.ui.ChannelSetup.java
public void saveMetaDataColumns() { DefaultTableModel model = (DefaultTableModel) metaDataTable.getModel(); List<MetaDataColumn> metaDataColumns = currentChannel.getProperties().getMetaDataColumns(); metaDataColumns.clear();/* w w w. ja va 2s .com*/ for (int i = 0; i < model.getRowCount(); i++) { MetaDataColumn column = new MetaDataColumn(); column.setName((String) model.getValueAt(i, 0)); column.setType((MetaDataColumnType) model.getValueAt(i, 1)); column.setMappingName((String) model.getValueAt(i, 2)); metaDataColumns.add(column); } }
From source file:com.mirth.connect.client.ui.ChannelSetup.java
/** * Save all of the current channel information in the editor to the actual channel *//* w w w .j ava2 s . c o m*/ public boolean saveChanges() { if (!parent.checkChannelName(summaryNameField.getText(), currentChannel.getId())) { return false; } if (metadataPruningOnRadio.isSelected() && metadataPruningDaysTextField.getText().equals("")) { parent.alertWarning(parent, "If metadata pruning is enabled, the age of metadata to prune cannot be blank."); return false; } if (contentPruningDaysRadio.isSelected() && contentPruningDaysTextField.getText().equals("")) { parent.alertWarning(parent, "If content pruning is enabled, the age of content to prune cannot be blank."); return false; } if (metadataPruningOnRadio.isSelected() && contentPruningDaysRadio.isSelected()) { Integer metadataPruningDays = Integer.parseInt(metadataPruningDaysTextField.getText()); Integer contentPruningDays = Integer.parseInt(contentPruningDaysTextField.getText()); if (contentPruningDays > metadataPruningDays) { parent.alertWarning(parent, "The age of content to prune cannot be greater than the age of metadata to prune."); return false; } } // Store the current metadata column data in a map with the column name as the key and the type as the value. Map<String, MetaDataColumnType> currentColumns = new HashMap<String, MetaDataColumnType>(); for (MetaDataColumn column : currentChannel.getProperties().getMetaDataColumns()) { currentColumns.put(column.getName(), column.getType()); } Set<String> columnNames = new HashSet<String>(); for (int i = 0; i < metaDataTable.getRowCount(); i++) { DefaultTableModel model = (DefaultTableModel) metaDataTable.getModel(); // Do not allow metadata column names to be empty String columnName = (String) model.getValueAt(i, model.findColumn(METADATA_NAME_COLUMN_NAME)); if (StringUtils.isEmpty(columnName)) { parent.alertWarning(parent, "Empty column name detected in custom metadata table. Column names cannot be empty."); return false; } else { // Do not allow duplicate column names if (columnNames.contains(columnName)) { parent.alertWarning(parent, "Duplicate column name detected in custom metadata table. Column names must be unique."); return false; } if (columnName.equalsIgnoreCase("MESSAGE_ID") || columnName.equalsIgnoreCase("METADATA_ID")) { parent.alertWarning(parent, columnName + " is a reserved keyword and cannot be used as a column name in the custom metadata table."); return false; } // Add the column name to a set so it can be checked for duplicates columnNames.add(columnName); } MetaDataColumnType columnType = (MetaDataColumnType) model.getValueAt(i, model.findColumn(METADATA_TYPE_COLUMN_NAME)); // Remove columns from the map only if they have NOT been modified in a way such that their data will be deleted on deploy if (currentColumns.containsKey(columnName) && currentColumns.get(columnName).equals(columnType)) { currentColumns.remove(columnName); } } // Notify the user if an existing column was modified in a way such that it will be deleted on deploy if (!currentColumns.isEmpty()) { if (!parent.alertOption(parent, "Renaming, deleting, or changing the type of existing custom metadata columns\nwill delete all existing data " + "for that column. Are you sure you want to do this?")) { return false; } } boolean enabled = summaryEnabledCheckbox.isSelected(); saveSourcePanel(); if (parent.currentContentPage == transformerPane) { transformerPane.accept(false); transformerPane.modified = false; // TODO: Check this. Fix to prevent double save on confirmLeave } if (parent.currentContentPage == filterPane) { filterPane.accept(false); filterPane.modified = false; // TODO: Check this. Fix to prevent double save on confirmLeave } saveDestinationPanel(); MessageStorageMode messageStorageMode = MessageStorageMode.fromInt(messageStorageSlider.getValue()); String errorString = getQueueErrorString(messageStorageMode); if (errorString != null) { parent.alertWarning(parent, StringUtils.capitalize(errorString) + " queueing must be disabled first before using the selected message storage mode."); return false; } currentChannel.setName(summaryNameField.getText()); currentChannel.setDescription(summaryDescriptionText.getText()); updateScripts(); setLastModified(); currentChannel.getProperties().setClearGlobalChannelMap(clearGlobalChannelMapCheckBox.isSelected()); currentChannel.getProperties().setEncryptData(encryptMessagesCheckBox.isSelected()); currentChannel.getProperties().setInitialState((DeployedState) initialState.getSelectedItem()); currentChannel.getProperties().setStoreAttachments(attachmentStoreCheckBox.isSelected()); String validationMessage = checkAllForms(currentChannel); if (validationMessage != null) { enabled = false; // If there is an error on one of the forms, then run the // validation on the current form to display any errors. if (channelView.getSelectedComponent() == destination) { // If the destination is enabled... if (currentChannel.getDestinationConnectors().get(destinationTable.getSelectedModelIndex()) .isEnabled()) { destinationConnectorPanel.checkProperties(destinationConnectorPanel.getProperties(), true); } } else if (channelView.getSelectedComponent() == source) { sourceConnectorPanel.checkProperties(sourceConnectorPanel.getProperties(), true); } summaryEnabledCheckbox.setSelected(false); parent.alertCustomError(this.parent, validationMessage, CustomErrorDialog.ERROR_SAVING_CHANNEL); } // Set the channel to enabled or disabled after it has been validated currentChannel.setEnabled(enabled); saveChannelTags(); saveMetaDataColumns(); saveMessageStorage(messageStorageMode); saveMessagePruning(); // Update resource names parent.updateResourceNames(currentChannel); for (ChannelTabPlugin channelTabPlugin : LoadedExtensions.getInstance().getChannelTabPlugins().values()) { channelTabPlugin.getChannelTabPanel().save(currentChannel); } boolean updated = false; try { // Will throw exception if the connection died or there was an exception // saving the channel, skipping the rest of this code. updated = parent.updateChannel(currentChannel, parent.channelPanel.getCachedChannelStatuses().containsKey(currentChannel.getId())); try { currentChannel = (Channel) SerializationUtils.clone( parent.channelPanel.getCachedChannelStatuses().get(currentChannel.getId()).getChannel()); if (parent.currentContentPage == transformerPane) { if (channelView.getSelectedIndex() == SOURCE_TAB_INDEX) { transformerPane.reload(currentChannel.getSourceConnector()); } else if (channelView.getSelectedIndex() == DESTINATIONS_TAB_INDEX) { int destination = destinationTable.getSelectedModelIndex(); transformerPane.reload(currentChannel.getDestinationConnectors().get(destination)); } } if (parent.currentContentPage == filterPane) { if (channelView.getSelectedIndex() == SOURCE_TAB_INDEX) { filterPane.reload(currentChannel.getSourceConnector(), currentChannel.getSourceConnector().getFilter()); } else if (channelView.getSelectedIndex() == DESTINATIONS_TAB_INDEX) { Connector destination = currentChannel.getDestinationConnectors() .get(destinationTable.getSelectedModelIndex()); filterPane.reload(destination, destination.getFilter()); } } updateRevision(); updateLastModified(); } catch (SerializationException e) { parent.alertThrowable(this.parent, e); } } catch (ClientException e) { parent.alertThrowable(this.parent, e); } sourceConnectorPanel.updateQueueWarning(currentChannel.getProperties().getMessageStorageMode()); destinationConnectorPanel.updateQueueWarning(currentChannel.getProperties().getMessageStorageMode()); if (updated && saveGroupId != null) { parent.channelPanel.addChannelToGroup(currentChannel.getId(), saveGroupId); saveGroupId = null; } return updated; }
From source file:de.tor.tribes.ui.windows.TribeTribeAttackFrame.java
private void editChangeAttacks(int pDirection) { int idx = jideTabbedPane1.getSelectedIndex(); if (idx == 1) { int[] rows = jVictimTable.getSelectedRows(); if (rows == null || rows.length == 0) { showInfo("Keine Ziele ausgewhlt"); return; }//from ww w .ja va2s . c om DefaultTableModel victimModel = (DefaultTableModel) jVictimTable.getModel(); for (int r : rows) { int row = jVictimTable.convertRowIndexToModel(r); int amount = (Integer) victimModel.getValueAt(row, jVictimTable.convertColumnIndexToModel(3)); if (pDirection != 0) { amount += pDirection; } else { try { amount = (Integer) jMaxAttacksPerVillage.getValue(); } catch (ClassCastException cce) { amount = 1; } } if (amount > 0) { victimModel.setValueAt(amount, row, jVictimTable.convertColumnIndexToModel(3)); } } String message = "Angriffe fr " + ((rows.length == 1) ? " ein Ziel" : rows.length + " Ziele ") + " angepasst"; showSuccess(message); updateInfo(); } else { //invalid tab showInfo("Diese Funktion ist nur fr Ziele verfgbar"); } }
From source file:de.tor.tribes.ui.windows.TribeTribeAttackFrame.java
/** * Create detail frames shown after calculation *///from w w w. j a v a 2s . c o m private void buildDetailedStatistics(HashMap<Village, String> attackMappings, List<Village> pNotAssignedVillages) { // <editor-fold defaultstate="collapsed" desc="Build not assigned source table"> Collections.sort(pNotAssignedVillages); DefaultTableModel sourcesModel = new javax.swing.table.DefaultTableModel(new Object[][] {}, new String[] { "Spieler", "Dorf" }) { private Class[] cTypes = new Class[] { Tribe.class, Village.class }; @Override public Class getColumnClass(int columnIndex) { return cTypes[columnIndex]; } }; for (Village notAssigned : pNotAssignedVillages) { Tribe t = notAssigned.getTribe(); if (t == null) { sourcesModel.addRow(new Object[] { Barbarians.getSingleton(), notAssigned }); } else { sourcesModel.addRow(new Object[] { t, notAssigned }); } } jNotAssignedSourcesTable.setModel(sourcesModel); TableRowSorter<TableModel> sourcesSorter = new TableRowSorter<TableModel>(sourcesModel); jNotAssignedSourcesTable.setRowSorter(sourcesSorter); DefaultTableCellRenderer headerRenderer = new SortableTableHeaderRenderer(); for (int i = 0; i < jNotAssignedSourcesTable.getColumnCount(); i++) { jNotAssignedSourcesTable.getColumn(jNotAssignedSourcesTable.getColumnName(i)) .setHeaderRenderer(headerRenderer); } jNotAssignedSourcesTable.revalidate(); //</editor-fold> // <editor-fold defaultstate="collapsed" desc="Build attacks per target table"> DefaultTableModel tableModel = new javax.swing.table.DefaultTableModel(new Object[][] {}, new String[] { "Spieler", "Dorf", "Angriffe" }) { Class[] types = new Class[] { Tribe.class, Village.class, String.class }; @Override public Class getColumnClass(int columnIndex) { return types[columnIndex]; } }; List<Village> notFullTargets = new LinkedList<Village>(); Iterator<Village> keys = attackMappings.keySet().iterator(); while (keys.hasNext()) { Village key = keys.next(); Tribe t = key.getTribe(); //int notAssignedAmount = attackMappings.get(key); String attackCount = attackMappings.get(key); String[] split = attackCount.split("/"); int notAssignedAmount = Integer.parseInt(split[1]) - Integer.parseInt(split[0]); if (t != Barbarians.getSingleton()) { tableModel.addRow(new Object[] { t, key, attackCount }); } else { tableModel.addRow(new Object[] { "Barbaren", key, attackCount }); } if (notAssignedAmount > 0) { notFullTargets.add(key); } } jTargetDetailsTable.setModel(tableModel); TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tableModel); jTargetDetailsTable.setRowSorter(sorter); DefaultTableCellRenderer coloredRenderer = new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component c = new DefaultTableCellRenderer().getTableCellRendererComponent(table, value, isSelected, hasFocus, row, row); String t = ((DefaultTableCellRenderer) c).getText(); ((DefaultTableCellRenderer) c).setText(t); DefaultTableModel model = (DefaultTableModel) table.getModel(); int r = table.convertRowIndexToModel(row); String sVal = (String) model.getValueAt(r, 2); String[] split = sVal.split("/"); long max = Long.parseLong(split[1]); long v = Long.parseLong(split[0]); long diff = max - v; Color back = Color.RED; if (v == 0) { //color stays red } else if (v == max) { back = Color.GREEN; } else { float posv = 100.0f * (float) diff / (float) max; posv = ((int) posv / 10) * 10; posv /= 100; Color LAST_SEGMENT = new Color(255, 100, 0); int red = (int) Math.rint( (float) LAST_SEGMENT.getRed() * (1.0f - posv) + (float) Color.YELLOW.getRed() * posv); int green = (int) Math.rint((float) LAST_SEGMENT.getGreen() * (1.0f - posv) + (float) Color.YELLOW.getGreen() * posv); int blue = (int) Math.rint( (float) LAST_SEGMENT.getBlue() * (1.0f - posv) + (float) Color.YELLOW.getBlue() * posv); if (red < 0) { red = 0; } if (green < 0) { green = 0; } if (blue < 0) { blue = 0; } if (red > 254) { red = 254; } if (green > 254) { green = 254; } if (blue > 254) { blue = 254; } back = new Color(red, green, blue); } DefaultTableCellRenderer renderer = ((DefaultTableCellRenderer) c); if (!isSelected) { renderer.setBackground(back); } return c; } }; jTargetDetailsTable.setDefaultRenderer(Village.class, coloredRenderer); jTargetDetailsTable.setDefaultRenderer(Integer.class, coloredRenderer); jTargetDetailsTable.setDefaultRenderer(String.class, coloredRenderer); jTargetDetailsTable.setDefaultRenderer(Tribe.class, coloredRenderer); for (int i = 0; i < jTargetDetailsTable.getColumnCount(); i++) { jTargetDetailsTable.getColumn(jTargetDetailsTable.getColumnName(i)).setHeaderRenderer(headerRenderer); } jTargetDetailsTable.revalidate(); //</editor-fold> }
From source file:de.tor.tribes.ui.windows.TribeTribeAttackFrame.java
/** * Add target villages externally (see DSWorkbenchMainFrame) * * @param pVillages/*from w ww.ja va 2 s . c o m*/ */ public void fireAddTargetsEvent(List<Village> pVillages) { DefaultTableModel victimModel = (DefaultTableModel) jVictimTable.getModel(); for (Village v : pVillages) { if (v != null) { boolean contains = false; for (int row = 0; row < victimModel.getRowCount(); row++) { if (victimModel.getValueAt(row, 1).equals(v)) { contains = true; break; } } if (!contains) { int maxAttacks = 1; try { maxAttacks = (Integer) jMaxAttacksPerVillage.getValue(); } catch (Exception e) { maxAttacks = 1; } if (v != null) { victimModel.addRow( new Object[] { v.getTribe(), v, jMarkTargetAsFake.isSelected(), maxAttacks, 0 }); } } } } updateInfo(); ((DefaultTableModel) jVictimTable.getModel()).fireTableDataChanged(); }
From source file:de.tor.tribes.ui.windows.TribeTribeAttackFrame.java
private void showAttackInfoEvent(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_showAttackInfoEvent DefaultTableModel victimModel = (DefaultTableModel) jVictimTable.getModel(); List<Village> victimVillages = new LinkedList<Village>(); List<Village> victimVillagesFaked = new LinkedList<Village>(); for (int i = 0; i < victimModel.getRowCount(); i++) { if ((Boolean) victimModel.getValueAt(i, 2) == Boolean.TRUE) { victimVillagesFaked.add((Village) victimModel.getValueAt(i, 1)); } else {//from ww w .j a v a 2 s . com victimVillages.add((Village) victimModel.getValueAt(i, 1)); } } DefaultTableModel attackModel = (DefaultTableModel) jSourcesTable.getModel(); Hashtable<UnitHolder, List<Village>> sources = new Hashtable<UnitHolder, List<Village>>(); Hashtable<UnitHolder, List<Village>> fakes = new Hashtable<UnitHolder, List<Village>>(); for (int i = 0; i < attackModel.getRowCount(); i++) { Village vSource = (Village) attackModel.getValueAt(i, 0); UnitHolder uSource = (UnitHolder) attackModel.getValueAt(i, 1); boolean fake = (Boolean) attackModel.getValueAt(i, 2); if (!fake) { List<Village> sourcesForUnit = sources.get(uSource); if (sourcesForUnit == null) { sourcesForUnit = new LinkedList<Village>(); sourcesForUnit.add(vSource); sources.put(uSource, sourcesForUnit); } else { sourcesForUnit.add(vSource); } } else { List<Village> fakesForUnit = fakes.get(uSource); if (fakesForUnit == null) { fakesForUnit = new LinkedList<Village>(); fakesForUnit.add(vSource); fakes.put(uSource, fakesForUnit); } else { fakesForUnit.add(vSource); } } } DSWorkbenchAttackInfoPanel info = new DSWorkbenchAttackInfoPanel(); info.setVillages(sources, victimVillages, fakes, victimVillagesFaked); JFrame f = new JFrame(); f.add(info); info.refresh(); f.setSize(info.getWidth(), info.getHeight()); f.pack(); f.setVisible(true); }
From source file:de.tor.tribes.ui.windows.TribeTribeAttackFrame.java
private void fireSynchWithAttackPlansEvent(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_fireSynchWithAttackPlansEvent jAttackPlanSelectionDialog.setVisible(false); if (evt.getSource() == jCancelSyncButton) { return;// w w w . j a va 2 s. c o m } int idx = jideTabbedPane1.getSelectedIndex(); JXTable table = null; int villageIndex = 0; if (idx == 0) { table = jSourcesTable; } else if (idx == 1) { table = jVictimTable; villageIndex = 1; } else { showInfo("Diese Funktion ist nur fr Herkunftsdrfer und Ziele verfgbar"); return; } DefaultTableModel model = (DefaultTableModel) jAttackPlanTable.getModel(); List<String> selectedPlans = new LinkedList<String>(); for (int i = 0; i < jAttackPlanTable.getRowCount(); i++) { int row = jAttackPlanTable.convertRowIndexToModel(i); if ((Boolean) model.getValueAt(row, jAttackPlanTable.convertColumnIndexToModel(1))) { selectedPlans.add((String) model.getValueAt(row, jAttackPlanTable.convertColumnIndexToModel(0))); } } List<Integer> toRemove = new LinkedList<Integer>(); //process all plans for (String plan : selectedPlans) { logger.debug("Checking plan '" + plan + "'"); List<ManageableType> elements = AttackManager.getSingleton().getAllElements(plan); //process all attacks for (ManageableType e : elements) { Attack a = (Attack) e; //search attack source village in all table rows for (int i = 0; i < table.getRowCount(); i++) { Village v = (Village) table.getValueAt(i, villageIndex); if (villageIndex == 0 && a.getSource().equals(v)) { if (!toRemove.contains(i)) { toRemove.add(i); } } else if (villageIndex == 1 && a.getTarget().equals(v)) { if (!toRemove.contains(i)) { toRemove.add(i); } } } } } String message = ""; if (toRemove.isEmpty()) { showInfo("Keine Drfer zu entfernen"); return; } else { message = (toRemove.size() == 1) ? "Ein Dorf " : toRemove.size() + " Drfer "; } if (JOptionPaneHelper.showQuestionConfirmBox(this, message + "entfernen?", "Entfernen", "Nein", "Ja") == JOptionPane.YES_OPTION) { try { logger.debug("Removing " + toRemove.size() + " villages"); Collections.sort(toRemove); while (toRemove.size() > 0) { Integer row = toRemove.remove(toRemove.size() - 1); row = table.convertRowIndexToModel(row); ((DefaultTableModel) table.getModel()).removeRow(row); } showSuccess(message + "entfernt"); } catch (Exception e) { logger.error("Removal failed", e); showError("Fehler beim Entfernen"); } } updateInfo(); }
From source file:de.tor.tribes.ui.windows.TribeTribeAttackFrame.java
private void editUseSnobs() { int idx = jideTabbedPane1.getSelectedIndex(); if (idx == 0) { //use snobs in villages where snobs exist DefaultTableModel model = (DefaultTableModel) jSourcesTable.getModel(); UnitHolder snob = DataHolder.getSingleton().getUnitByPlainName("snob"); jSourcesTable.invalidate();//from www.ja va2 s . c om Hashtable<Village, Integer> assignedTroops = new Hashtable<Village, Integer>(); for (int row = 0; row < model.getRowCount(); row++) { Village v = (Village) model.getValueAt(row, jSourcesTable.convertColumnIndexToModel(0)); VillageTroopsHolder troops = TroopsManager.getSingleton().getTroopsForVillage(v, TroopsManager.TROOP_TYPE.IN_VILLAGE); if (troops != null) { int availSnobs = troops.getTroopsOfUnitInVillage(snob); Integer assignedSnobs = assignedTroops.get(v); if (assignedSnobs == null) { assignedSnobs = 0; } else { assignedSnobs += 1; } availSnobs -= assignedSnobs; assignedTroops.put(v, assignedSnobs); //snob avail if (availSnobs > 0) { model.setValueAt(snob, row, jSourcesTable.convertColumnIndexToModel(1)); } } } showInfo("Vorhandene AGs eingetragen"); } else { showInfo("Diese Funktion ist nur fr Herkunftsdrfer verfgbar"); } }
From source file:de.tor.tribes.ui.windows.TribeTribeAttackFrame.java
private void miscSplit() { if (jideTabbedPane1.getSelectedIndex() == 0) { DefaultTableModel model = (DefaultTableModel) jSourcesTable.getModel(); int sources = model.getRowCount(); if (sources == 0) { showInfo("Keine Herkunftsdrfer eingetragen"); return; }/*w w w. j av a 2 s . co m*/ List<Village> sourceVillages = new LinkedList<Village>(); Hashtable<Village, UnitHolder> attTable = new Hashtable<Village, UnitHolder>(); Hashtable<Village, UnitHolder> fakeTable = new Hashtable<Village, UnitHolder>(); for (int i = 0; i < sources; i++) { Village sourceVillage = (Village) model.getValueAt(i, jSourcesTable.convertColumnIndexToModel(0)); if (!sourceVillages.contains(sourceVillage)) { sourceVillages.add(sourceVillage); boolean fake = (Boolean) jSourcesTable.getValueAt(i, jSourcesTable.convertColumnIndexToModel(2)); UnitHolder unit = (UnitHolder) jSourcesTable.getValueAt(i, jSourcesTable.convertColumnIndexToModel(1)); if (fake) { fakeTable.put(sourceVillage, unit); } else { attTable.put(sourceVillage, unit); } } } mTroopSplitDialog.setupAndShow(sourceVillages); TroopSplit[] splits = mTroopSplitDialog.getSplits(); if (splits.length == 0) { //canceled return; } for (int i = sources - 1; i >= 0; i--) { model.removeRow(i); } int overallSplitCount = 0; for (TroopSplit split : splits) { overallSplitCount += split.getSplitCount(); for (int i = 0; i < split.getSplitCount(); i++) { boolean isFake = false; UnitHolder unit = attTable.get(split.getVillage()); if (unit == null) { unit = fakeTable.get(split.getVillage()); isFake = true; } model.addRow(new Object[] { split.getVillage(), unit, isFake, 0 }); } } String message = ((sourceVillages.size() == 1) ? "Herkunftsdorf " : sourceVillages.size() + " Herkunftsdrfer ") + ((overallSplitCount == 1) ? "einmal" : overallSplitCount + " mal ") + " geteilt"; showSuccess(message); } else { showInfo("Diese Funktion ist nur fr Herkunftsdrfer verfgbar"); } }