Explorar o código

more bugcases fixed

LH %!s(int64=7) %!d(string=hai) anos
pai
achega
b19e601815

+ 3 - 2
iZpl/src/main/java/de/nplusc/izc/iZpl/API/PlayListEditAPI.java

@@ -4,6 +4,7 @@
  */
 package de.nplusc.izc.iZpl.API;
 
+import de.nplusc.izc.iZpl.API.shared.InvalidPlayListFileException;
 import de.nplusc.izc.iZpl.API.shared.SinglePlayListItem;
 import de.nplusc.izc.iZpl.API.shared.PlayListItem;
 import de.nplusc.izc.iZpl.API.shared.MultiPlayListItem;
@@ -131,7 +132,7 @@ public class PlayListEditAPI
      * obtains the listing of the track titles
      * @return Array with the list ordered in the internal ordering
      */
-    public static String[] getTrackTitles()
+    public static String[] getTrackTitles() throws InvalidPlayListFileException
     {
         String[] tt = new String[playListItemKeys.size()];
         for (int i=0;i<playListItemKeys.size();i++)
@@ -141,7 +142,7 @@ public class PlayListEditAPI
             if(x==null)
             {
                 Main.getPLServer().getPlProcessorV2().getPool().remove(k);
-                continue;
+                throw new InvalidPlayListFileException("Statefile corrupted");
             }
             if(x instanceof MultiPlayListItem)
             {

+ 335 - 319
iZpl/src/main/java/de/nplusc/izc/iZpl/GUI/PlayListManagingDefault.java

@@ -1,319 +1,335 @@
-/*
- * Copyright (C) 2015 iZc
- *
- * This program 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.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package de.nplusc.izc.iZpl.GUI;
-
-import de.nplusc.izc.iZpl.API.IZPLApi;
-import de.nplusc.izc.iZpl.API.PlayListEditAPI;
-import de.nplusc.izc.tools.UiToolz.TableCellListener;
-import de.nplusc.izc.tools.baseTools.HidableTableColumnModel;
-import java.awt.event.ActionEvent;
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.table.DefaultTableModel;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- *
- * @author LH
- */
-public class PlayListManagingDefault extends javax.swing.JFrame implements PlayListManagingCommon
-{
-    private static final Logger l = LogManager.getLogger();
-    private HidableTableColumnModel mdl;
-   
-    /**
-     * Creates new form PlayListManagingDefault
-     */
-    public PlayListManagingDefault()
-    {
-        setIconImage(IZPLApi.getProgramIcon());
-        initComponents();
-        mdl=(HidableTableColumnModel) tblPLE.getColumnModel();
-        mdl.setColumnVisible(mdl.getColumn(0), false);
-        Action action = new AbstractAction()
-        {
-            public void actionPerformed(ActionEvent e)
-            {
-                if(!rebuilding)
-                {
-                    TableCellListener tcl = (TableCellListener)e.getSource();
-                    l.trace("Row   : " + tcl.getRow());
-                    l.trace("Value  : " + tcl.getNewValue());
-                    PlayListEditAPI.setTargetPlayCount(tcl.getRow(), (int) tcl.getNewValue());
-                }
-            }
-        };
-
-        TableCellListener tcl = new TableCellListener(tblPLE, action);
-        
-    }
-
-    /**
-     * 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()
-    {
-
-        jScrollPane1 = new javax.swing.JScrollPane();
-        tblPLE = new javax.swing.JTable();
-        jPanel1 = new javax.swing.JPanel();
-        btnForce = new javax.swing.JButton();
-        btnReload = new javax.swing.JButton();
-        btnClose = new javax.swing.JButton();
-
-        setTitle("Edit PlayList Data");
-
-        tblPLE.setModel(new javax.swing.table.DefaultTableModel(
-            new Object [][]
-            {
-                {null, null, null, null},
-                {null, null, null, null},
-                {null, null, null, null},
-                {null, null, null, null}
-            },
-            new String []
-            {
-                "ID", "Element-Titel", "# to Play", "# Played"
-            }
-        )
-        {
-            Class[] types = new Class []
-            {
-                java.lang.Integer.class, java.lang.String.class, java.lang.Integer.class, java.lang.Integer.class
-            };
-            boolean[] canEdit = new boolean []
-            {
-                false, false, true, false
-            };
-
-            public Class getColumnClass(int columnIndex)
-            {
-                return types [columnIndex];
-            }
-
-            public boolean isCellEditable(int rowIndex, int columnIndex)
-            {
-                return canEdit [columnIndex];
-            }
-        });
-        tblPLE.setColumnModel (new HidableTableColumnModel(tblPLE.getColumnModel()));
-        tblPLE.setAutoCreateRowSorter (true);
-        jScrollPane1.setViewportView(tblPLE);
-        if (tblPLE.getColumnModel().getColumnCount() > 0)
-        {
-            tblPLE.getColumnModel().getColumn(0).setResizable(false);
-            tblPLE.getColumnModel().getColumn(2).setMinWidth(80);
-            tblPLE.getColumnModel().getColumn(2).setPreferredWidth(80);
-            tblPLE.getColumnModel().getColumn(2).setMaxWidth(80);
-            tblPLE.getColumnModel().getColumn(3).setMinWidth(80);
-            tblPLE.getColumnModel().getColumn(3).setPreferredWidth(80);
-            tblPLE.getColumnModel().getColumn(3).setMaxWidth(80);
-        }
-
-        btnForce.setText("Als näxxtes setzen");
-        btnForce.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
-                btnForceActionPerformed(evt);
-            }
-        });
-
-        btnReload.setText("Neu Laden");
-        btnReload.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
-                btnReloadActionPerformed(evt);
-            }
-        });
-
-        btnClose.setText("Schließen");
-        btnClose.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
-                btnCloseActionPerformed(evt);
-            }
-        });
-
-        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
-        jPanel1.setLayout(jPanel1Layout);
-        jPanel1Layout.setHorizontalGroup(
-            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addComponent(btnForce, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-            .addComponent(btnReload, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-            .addComponent(btnClose, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-        );
-        jPanel1Layout.setVerticalGroup(
-            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(jPanel1Layout.createSequentialGroup()
-                .addContainerGap()
-                .addComponent(btnForce)
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
-                .addComponent(btnReload)
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(btnClose))
-        );
-
-        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
-        getContentPane().setLayout(layout);
-        layout.setHorizontalGroup(
-            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
-                .addContainerGap()
-                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 735, Short.MAX_VALUE)
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addContainerGap())
-        );
-        layout.setVerticalGroup(
-            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE)
-                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                .addContainerGap())
-        );
-
-        pack();
-    }// </editor-fold>//GEN-END:initComponents
-
-    private void btnReloadActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnReloadActionPerformed
-    {//GEN-HEADEREND:event_btnReloadActionPerformed
-   
-        if((evt.getModifiers()& ActionEvent.SHIFT_MASK)!=0)
-        {
-            PlayListEditAPI.reloadList();
-        }
-        rebuildTable();
-    }//GEN-LAST:event_btnReloadActionPerformed
-
-    private void btnCloseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnCloseActionPerformed
-    {//GEN-HEADEREND:event_btnCloseActionPerformed
-       setVisible(false);
-    }//GEN-LAST:event_btnCloseActionPerformed
-
-    private void btnForceActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnForceActionPerformed
-    {//GEN-HEADEREND:event_btnForceActionPerformed
-       int viewRow = tblPLE.getSelectedRow();
-        viewRow = tblPLE.convertRowIndexToModel(viewRow);
-        
-        PlayListEditAPI.forceElement((Integer)((DefaultTableModel)tblPLE.getModel()).getValueAt(viewRow,0));
-    }//GEN-LAST:event_btnForceActionPerformed
-
-    /**
-     * @param args the command line arguments
-     */
-    public static void main(String args[])
-    {
-        /* Set the Nimbus look and feel */
-        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
-        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
-         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
-         */
-        try
-        {
-            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
-            {
-                if ("Nimbus".equals(info.getName()))
-                {
-                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
-                    break;
-                }
-            }
-        }
-        catch (ClassNotFoundException ex)
-        {
-            java.util.logging.Logger.getLogger(PlayListManagingDefault.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
-        }
-        catch (InstantiationException ex)
-        {
-            java.util.logging.Logger.getLogger(PlayListManagingDefault.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
-        }
-        catch (IllegalAccessException ex)
-        {
-            java.util.logging.Logger.getLogger(PlayListManagingDefault.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
-        }
-        catch (javax.swing.UnsupportedLookAndFeelException ex)
-        {
-            java.util.logging.Logger.getLogger(PlayListManagingDefault.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
-        }
-        //</editor-fold>
-
-        /* Create and display the form */
-        java.awt.EventQueue.invokeLater(new Runnable()
-        {
-            public void run()
-            {
-                new PlayListManagingDefault().setVisible(true);
-            }
-        });
-    }
-    
-    private boolean rebuilding=false;
-    private void rebuildTable()
-    {
-        rebuilding = true;
-        //mdl.setAllColumnsVisible();
-        PlayListEditAPI.refreshKeyList();
-        String[] titles = PlayListEditAPI.getTrackTitles();
-        for(int i=tblPLE.getRowCount()-1;i>0;i--)
-	{
-	    ((DefaultTableModel)tblPLE.getModel()).removeRow(i-1);
-	}
-            tblPLE.getModel().setValueAt(0,0,0);
-            tblPLE.getModel().setValueAt(titles[0],0,1);
-            tblPLE.getModel().setValueAt(PlayListEditAPI.getTargetPlayCount(0),0,2);
-            tblPLE.getModel().setValueAt(PlayListEditAPI.getPlayCount(0),0,3);
-        for (int i = 0; i < titles.length; i++)
-        {
-            ((DefaultTableModel)tblPLE.getModel()).addRow(new Object[]{null,null,null,null});
-            tblPLE.getModel().setValueAt(i,i,0);
-            tblPLE.getModel().setValueAt(titles[i],i,1);
-            tblPLE.getModel().setValueAt(PlayListEditAPI.getTargetPlayCount(i),i,2);
-            tblPLE.getModel().setValueAt(PlayListEditAPI.getPlayCount(i),i,3);
-        }
-        rebuilding=false;
-        //mdl.setColumnVisible(0, false);
-    }
-    
-    
-    
-    // Variables declaration - do not modify//GEN-BEGIN:variables
-    private javax.swing.JButton btnClose;
-    private javax.swing.JButton btnForce;
-    private javax.swing.JButton btnReload;
-    private javax.swing.JPanel jPanel1;
-    private javax.swing.JScrollPane jScrollPane1;
-    private javax.swing.JTable tblPLE;
-    // End of variables declaration//GEN-END:variables
-
-    @Override
-    public void setVisibleAux(boolean state)
-    {
-        setVisible(state);
-        rebuildTable();
-    }
-}
+/*
+ * Copyright (C) 2015 iZc
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.nplusc.izc.iZpl.GUI;
+
+import de.nplusc.izc.iZpl.API.IZPLApi;
+import de.nplusc.izc.iZpl.API.PlayListEditAPI;
+import de.nplusc.izc.iZpl.API.shared.InvalidPlayListFileException;
+import de.nplusc.izc.tools.UiToolz.TableCellListener;
+import de.nplusc.izc.tools.baseTools.HidableTableColumnModel;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.table.DefaultTableModel;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+/**
+ *
+ * @author LH
+ */
+public class PlayListManagingDefault extends javax.swing.JFrame implements PlayListManagingCommon
+{
+    private static final Logger l = LogManager.getLogger();
+    private HidableTableColumnModel mdl;
+   
+    /**
+     * Creates new form PlayListManagingDefault
+     */
+    public PlayListManagingDefault()
+    {
+        setIconImage(IZPLApi.getProgramIcon());
+        initComponents();
+        mdl=(HidableTableColumnModel) tblPLE.getColumnModel();
+        mdl.setColumnVisible(mdl.getColumn(0), false);
+        Action action = new AbstractAction()
+        {
+            public void actionPerformed(ActionEvent e)
+            {
+                if(!rebuilding)
+                {
+                    TableCellListener tcl = (TableCellListener)e.getSource();
+                    l.trace("Row   : " + tcl.getRow());
+                    l.trace("Value  : " + tcl.getNewValue());
+                    PlayListEditAPI.setTargetPlayCount(tcl.getRow(), (int) tcl.getNewValue());
+                }
+            }
+        };
+
+        TableCellListener tcl = new TableCellListener(tblPLE, action);
+        
+    }
+
+    /**
+     * 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()
+    {
+
+        jScrollPane1 = new javax.swing.JScrollPane();
+        tblPLE = new javax.swing.JTable();
+        jPanel1 = new javax.swing.JPanel();
+        btnForce = new javax.swing.JButton();
+        btnReload = new javax.swing.JButton();
+        btnClose = new javax.swing.JButton();
+
+        setTitle("Edit PlayList Data");
+
+        tblPLE.setModel(new javax.swing.table.DefaultTableModel(
+            new Object [][]
+            {
+                {null, null, null, null},
+                {null, null, null, null},
+                {null, null, null, null},
+                {null, null, null, null}
+            },
+            new String []
+            {
+                "ID", "Element-Titel", "# to Play", "# Played"
+            }
+        )
+        {
+            Class[] types = new Class []
+            {
+                java.lang.Integer.class, java.lang.String.class, java.lang.Integer.class, java.lang.Integer.class
+            };
+            boolean[] canEdit = new boolean []
+            {
+                false, false, true, false
+            };
+
+            public Class getColumnClass(int columnIndex)
+            {
+                return types [columnIndex];
+            }
+
+            public boolean isCellEditable(int rowIndex, int columnIndex)
+            {
+                return canEdit [columnIndex];
+            }
+        });
+        tblPLE.setColumnModel (new HidableTableColumnModel(tblPLE.getColumnModel()));
+        tblPLE.setAutoCreateRowSorter (true);
+        jScrollPane1.setViewportView(tblPLE);
+        if (tblPLE.getColumnModel().getColumnCount() > 0)
+        {
+            tblPLE.getColumnModel().getColumn(0).setResizable(false);
+            tblPLE.getColumnModel().getColumn(2).setMinWidth(80);
+            tblPLE.getColumnModel().getColumn(2).setPreferredWidth(80);
+            tblPLE.getColumnModel().getColumn(2).setMaxWidth(80);
+            tblPLE.getColumnModel().getColumn(3).setMinWidth(80);
+            tblPLE.getColumnModel().getColumn(3).setPreferredWidth(80);
+            tblPLE.getColumnModel().getColumn(3).setMaxWidth(80);
+        }
+
+        btnForce.setText("Als näxxtes setzen");
+        btnForce.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                btnForceActionPerformed(evt);
+            }
+        });
+
+        btnReload.setText("Neu Laden");
+        btnReload.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                btnReloadActionPerformed(evt);
+            }
+        });
+
+        btnClose.setText("Schließen");
+        btnClose.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                btnCloseActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(btnForce, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+            .addComponent(btnReload, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+            .addComponent(btnClose, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(btnForce)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(btnReload)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addComponent(btnClose))
+        );
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+        getContentPane().setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 735, Short.MAX_VALUE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE)
+                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                .addContainerGap())
+        );
+
+        pack();
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void btnReloadActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnReloadActionPerformed
+    {//GEN-HEADEREND:event_btnReloadActionPerformed
+   
+        if((evt.getModifiers()& ActionEvent.SHIFT_MASK)!=0)
+        {
+            PlayListEditAPI.reloadList();
+        }
+        rebuildTable(false);
+    }//GEN-LAST:event_btnReloadActionPerformed
+
+    private void btnCloseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnCloseActionPerformed
+    {//GEN-HEADEREND:event_btnCloseActionPerformed
+       setVisible(false);
+    }//GEN-LAST:event_btnCloseActionPerformed
+
+    private void btnForceActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnForceActionPerformed
+    {//GEN-HEADEREND:event_btnForceActionPerformed
+       int viewRow = tblPLE.getSelectedRow();
+        viewRow = tblPLE.convertRowIndexToModel(viewRow);
+        
+        PlayListEditAPI.forceElement((Integer)((DefaultTableModel)tblPLE.getModel()).getValueAt(viewRow,0));
+    }//GEN-LAST:event_btnForceActionPerformed
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String args[])
+    {
+        /* Set the Nimbus look and feel */
+        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
+        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
+         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
+         */
+        try
+        {
+            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
+            {
+                if ("Nimbus".equals(info.getName()))
+                {
+                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
+                    break;
+                }
+            }
+        }
+        catch (ClassNotFoundException ex)
+        {
+            java.util.logging.Logger.getLogger(PlayListManagingDefault.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+        }
+        catch (InstantiationException ex)
+        {
+            java.util.logging.Logger.getLogger(PlayListManagingDefault.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+        }
+        catch (IllegalAccessException ex)
+        {
+            java.util.logging.Logger.getLogger(PlayListManagingDefault.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+        }
+        catch (javax.swing.UnsupportedLookAndFeelException ex)
+        {
+            java.util.logging.Logger.getLogger(PlayListManagingDefault.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+        }
+        //</editor-fold>
+
+        /* Create and display the form */
+        java.awt.EventQueue.invokeLater(new Runnable()
+        {
+            public void run()
+            {
+                new PlayListManagingDefault().setVisible(true);
+            }
+        });
+    }
+    
+    private boolean rebuilding=false;
+    private void rebuildTable(boolean recovery)
+    {
+        try{
+        rebuilding = true;
+        
+        //mdl.setAllColumnsVisible();
+        PlayListEditAPI.refreshKeyList();
+        String[] titles = PlayListEditAPI.getTrackTitles();
+        for(int i=tblPLE.getRowCount()-1;i>0;i--)
+	{
+	    ((DefaultTableModel)tblPLE.getModel()).removeRow(i-1);
+	}
+            tblPLE.getModel().setValueAt(0,0,0);
+            tblPLE.getModel().setValueAt(titles[0],0,1);
+            tblPLE.getModel().setValueAt(PlayListEditAPI.getTargetPlayCount(0),0,2);
+            tblPLE.getModel().setValueAt(PlayListEditAPI.getPlayCount(0),0,3);
+        for (int i = 0; i < titles.length; i++)
+        {
+            ((DefaultTableModel)tblPLE.getModel()).addRow(new Object[]{null,null,null,null});
+            tblPLE.getModel().setValueAt(i,i,0);
+            tblPLE.getModel().setValueAt(titles[i],i,1);
+            tblPLE.getModel().setValueAt(PlayListEditAPI.getTargetPlayCount(i),i,2);
+            tblPLE.getModel().setValueAt(PlayListEditAPI.getPlayCount(i),i,3);
+        }
+        rebuilding=false;
+        }
+        catch(InvalidPlayListFileException e)
+        {
+             rebuilding=false;
+            if(recovery)
+            {
+                l.error("Serious statefile corruption detected");
+                IZPLApi.quickQuitWithoutSaving();
+            }
+            //reloading data from disk and flushing internal references when the resume state got corrupted from a encoding change
+            PlayListEditAPI.reloadList();
+            rebuildTable(recovery);
+        }
+        //mdl.setColumnVisible(0, false);
+    }
+    
+    
+    
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton btnClose;
+    private javax.swing.JButton btnForce;
+    private javax.swing.JButton btnReload;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JTable tblPLE;
+    // End of variables declaration//GEN-END:variables
+
+    @Override
+    public void setVisibleAux(boolean state)
+    {
+        setVisible(state);
+        rebuildTable(false);
+    }
+}

+ 822 - 804
iZpl/src/main/java/de/nplusc/izc/iZpl/GUI/PlayListManagingSkinnable.java

@@ -1,804 +1,822 @@
-/*
- * Copyright (C) 2015 iZc
- *
- * This program 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.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package de.nplusc.izc.iZpl.GUI;
-
-import de.nplusc.izc.iZpl.API.PlayListEditAPI;
-import com.sun.awt.AWTUtilities;
-import de.nplusc.izc.iZpl.API.IZPLApi;
-import de.nplusc.izc.tools.UiToolz.ComponentMover;
-import de.nplusc.izc.tools.UiToolz.HoloJPanel;
-import de.nplusc.izc.tools.UiToolz.HoloSliderUi;
-import de.nplusc.izc.tools.UiToolz.IZSkinFile;
-import de.nplusc.izc.tools.baseTools.Messagers;
-import de.nplusc.izc.tools.baseTools.Tools;
-import de.schlichtherle.truezip.file.TFileInputStream;
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Container;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.Polygon;
-import java.awt.Window;
-import java.awt.event.ActionEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import javax.imageio.ImageIO;
-import javax.swing.JDialog;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JSlider;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- *
- * @author LH
- */
-public class PlayListManagingSkinnable extends JPanel implements MouseMotionListener , MouseListener,PlayListManagingCommon
-{
-    private static final Logger l = LogManager.getLogger();
-    
-    public static final int BUTTON_NONE_ID=0;
-    public static final int BUTTON_IXX_ID=1;
-    public static final int BUTTON_MIN_ID=2;
-    public static final int BUTTON_HIDE_ID=3;
-    public static final int BUTTON_RELOAD_ID=4;
-    public static final int BUTTON_FORCE_ID=5;
-    
-    public static final boolean STATE_HILIT=false;
-    public static final boolean STATE_CLICKED=!STATE_HILIT;
-    public static final Color TransBgColor = new Color(0, 0, 0, 0);
-    
-    private final String bdir;
-    private final IZSkinFile sf;
-    private final int h,w;
-    private final ComponentMover m;
-    private final JSlider s;
-    private final Color txc;
-    private final Color selected;
-    private int textColorR,selectedColorR;
-    private String[] titles;
-    private final JPanel titlebar;
-    private final Image paintme,background,buttonIxxClicked,buttonIxxHilit,buttonMinClicked,buttonMinHilit,buttonHideClicked,buttonHideHilit,
-                    buttonReloadHilit,buttonReloadClicked,buttonForceClicked,buttonForceHilit,sliderknob;
-    private final HoloJPanel PA;
-    //definieren die heißen zonen....
-    private final Polygon buttonIxx,buttonMin,buttonHide,buttonReload,buttonForce;
-    private int tablewidth=500,tableheight=500,lineheight=15;//defaultwerte wenn exception fliegt
-    //private final int defaultlc=0x000000,hilitcolor=0xffff00,selected=0xff7700;
-    private final int lc;//dynamish generiert im konstruktor; lazyness...
-    private int titlebarwidth;
-    JLabel[] th;//datenjonglage die 2.
-    private final Window wrapper;
-    private int selectedLine=-1;
-    private boolean unmoveable=false;
-    
-    
-    JLabel[][] tab;//datenjonglage...
-    @SuppressWarnings("empty-statement")
-    public PlayListManagingSkinnable(Window wrapper,String skinPath,IZSkinFile sfp)
-    {
-        if(wrapper instanceof JFrame)
-        {
-            wrapper.setIconImage(IZPLApi.getProgramIcon());
-        }
-        this.wrapper=wrapper;
-        bdir=skinPath;
-        sf=sfp;
-        @SuppressWarnings("null")
-        HashMap<String,String> ed=sf.getElementData();
-        HashMap<String,ArrayList<Integer>> ep = sf.getElementPositions();
-        
-        //separate exceptions sind gewollt um mitzuteilen welcher key fail'd
-        try{
-            tablewidth = Integer.valueOf(ed.get("tablewidth"));
-        }
-        catch(NumberFormatException lickme)
-        {
-            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für tablewidth");
-            IZPLApi.quickQuitWithoutSaving();
-        }
-        try{
-            titlebarwidth = Integer.valueOf(ed.get("titlebarwidth"));
-        }
-        catch(NumberFormatException lickme)
-        {
-            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für titlebarwidth");
-            IZPLApi.quickQuitWithoutSaving();
-        }
-                try{
-            titlebarwidth = Integer.valueOf(ed.get("titlebarwidth"));
-        }
-        catch(NumberFormatException lickme)
-        {
-            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für titlebarwidth");
-            IZPLApi.quickQuitWithoutSaving();
-        }
-        try{
-           textColorR = Integer.valueOf(ed.get("textcolor").substring(2),16);
-        }
-        catch(NumberFormatException lickme)
-        {
-            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für tableheight");
-            IZPLApi.quickQuitWithoutSaving();
-        }
-        try{
-           selectedColorR = Integer.valueOf(ed.get("textcolormarked").substring(2),16);
-        }
-        catch(NumberFormatException lickme)
-        {
-            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für tableheight");
-            IZPLApi.quickQuitWithoutSaving();
-        }
-        try{
-            lineheight = Integer.valueOf(ed.get("lineheight"));
-        }
-        catch(NumberFormatException lickme)
-        {
-            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für lineheight");
-            IZPLApi.quickQuitWithoutSaving();
-        }
-        if(wrapper instanceof JFrame)
-        {
-        ((JFrame)wrapper).setUndecorated(true);
-        }
-        else if(wrapper instanceof JDialog)
-        {
-        ((JDialog)wrapper).setUndecorated(true);
-        }
-        else
-        {
-            throw new UnsupportedOperationException("Only JFrame or JDialog supported");
-        }
-        boolean tp = AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT);
-        if(tp)
-        {
-            AWTUtilities.setWindowOpaque(wrapper, false);//freischalten von irregularShapes
-            //AWTUtilities.
-        }
-        background = loadImageAux(ed.get("backgroundlayer"));
-        paintme = loadImageAux(ed.get("backgroundlayer"));//background ist default deshalb doppeltgemoppelt; auf paintme wird später rumgepinselt
-        buttonIxxHilit = loadImageAux(ed.get("button_IXX_hilit"));
-        buttonIxxClicked = loadImageAux(ed.get("button_IXX_clicked"));
-        buttonMinHilit = loadImageAux(ed.get("button_min_hilit"));;
-        buttonMinClicked = loadImageAux(ed.get("button_min_clicked"));
-        buttonHideClicked = loadImageAux(ed.get("button_hide_clicked"));
-        buttonHideHilit = loadImageAux(ed.get("button_hide_hilit"));
-        buttonReloadClicked = loadImageAux(ed.get("button_reload_clicked"));;
-        buttonReloadHilit = loadImageAux(ed.get("button_reload_hilit"));
-        buttonForceClicked = loadImageAux(ed.get("button_force_clicked"));
-        buttonForceHilit = loadImageAux(ed.get("button_force_hilit"));
-        sliderknob=loadImageAux(ed.get("scrollbarknob"));
-        
-        
-        while(background.getHeight(null)<=0);  //absicern dass image geladen...
-        while(paintme.getHeight(null)<=0);  //absicern dass image geladen...
-        h = background.getHeight(null);
-        w = background.getWidth(null);
-        setSize(w, h);
-        wrapper.setSize(w, h);
-        PA= new HoloJPanel();
-        PA.setSize(w,h);
-        PA.setOpaque(false);
-        setOpaque(false);
-        //int[] ixb = ep.get("button_IXX");
-        //paintme.getGraphics().drawImage(buttonIxxHilit, ixb[0], ixb[1], null);
-        PA.setdrawIMG(paintme);
-        add(PA);
-        l.info("skindim="+w+"|"+h);
-        
-        Container cp = null;
-        if(wrapper instanceof JFrame)
-        {
-            cp = ((JFrame)wrapper).getContentPane();
-        
-        }
-        else
-        {
-            cp=((JDialog)wrapper).getContentPane();
-        }
-        cp.setLayout(null);
-        while(buttonIxxHilit.getHeight(null)<=0);
-        while(buttonIxxClicked.getHeight(null)<=0);
-        while(buttonMinHilit.getHeight(null)<=0);
-        while(buttonMinClicked.getHeight(null)<=0);
-        while(buttonHideClicked.getHeight(null)<=0);
-        while(buttonHideHilit.getHeight(null)<=0);
-        while(buttonReloadClicked.getHeight(null)<=0);
-        while(buttonReloadHilit.getHeight(null)<=0);
-        while(buttonForceClicked.getHeight(null)<=0);
-        while(buttonForceHilit.getHeight(null)<=0);
-        while(sliderknob.getHeight(null)<=0); //absicern dass image geladen...
-        PA.addMouseListener(this);
-        PA.addMouseMotionListener(this);
-        addMouseListener(this);
-        addMouseMotionListener(this);
-        HoloJPanel p = new HoloJPanel();
-        PA.setLayout(null);
-        //BufferedImage b = new BufferedImage(700, 30, BufferedImage.TYPE_4BYTE_ABGR);
-        //b.getGraphics().setColor(Color.BLACK);
-        //b.getGraphics().fillRect(0, 0, 700, 30);
-        p.setdrawIMG(background);
-        
-        p.setSize(titlebarwidth,30);
-        titlebar=p;
-        PA.add(p);
-        m=new ComponentMover(wrapper.getClass());
-        m.registerComponent(p);
-        //ermöglichen der buttonerkennung...
-        boolean buttondetected = true;
-        buttonIxx = new Polygon();
-        int i = 1;
-        while (buttondetected)
-        {
-            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_IXX");
-            List<Integer> data = (List<Integer>) ep.get("button_IXX_point_" + i);
-            buttonIxx.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
-            i++;
-            buttondetected = ep.containsKey("button_IXX_point_" + i);
-        }
-        buttondetected = true;
-        buttonMin = new Polygon();
-        i = 1;
-        while (buttondetected)
-        {
-            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_min");
-            List<Integer> data = (List<Integer>) ep.get("button_min_point_" + i);
-            buttonMin.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
-            i++;
-            buttondetected = ep.containsKey("button_min_point_" + i);
-        }
-        buttondetected = true;
-        buttonHide = new Polygon();
-        i = 1;
-        while (buttondetected)
-        {
-            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_hide");
-            List<Integer> data = (List<Integer>) ep.get("button_hide_point_" + i);
-            buttonHide.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
-            i++;
-            buttondetected = ep.containsKey("button_hide_point_" + i);
-        }
-        buttondetected = true;
-        buttonForce = new Polygon();
-        i = 1;
-        while (buttondetected)
-        {
-            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_force");
-            List<Integer> data = (List<Integer>) ep.get("button_force_point_" + i);
-            buttonForce.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
-            i++;
-            buttondetected = ep.containsKey("button_force_point_" + i);
-        }
-        buttondetected = true;
-        buttonReload = new Polygon();
-        i = 1;
-        while (buttondetected)
-        {
-            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_reload");
-            List<Integer> data = (List<Integer>) ep.get("button_reload_point_" + i);
-            buttonReload.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
-            i++;
-            buttondetected = ep.containsKey("button_reload_point_" + i);
-        }
-        
-        txc=new Color(textColorR);
-        selected=new Color(selectedColorR);
-        
-        //generate_table
-        int l2p=tablewidth-160,l3p=tablewidth-80;
-        PA.setLayout(null);
-        lc = tableheight/lineheight-1;//oberste zeile=header
-        ArrayList<Integer> tbb = (ArrayList<Integer>) ep.get("tablestart");
-        l.trace("tw(l2p,l3p),th,lc,lh|tbb[0],tbb[1]=>"+tablewidth+"("+l2p+","+l3p+"),"+tableheight+","+lc+","+lineheight+"|"+tbb.get(0)+","+tbb.get(1));
-        th = new JLabel[3];
-        th[0] = new JLabel("Element-Titel");
-        th[0].setForeground(txc);
-        th[0].setBounds(tbb.get(0), tbb.get(1), l2p, lineheight);
-        th[1] = new JLabel("# to play");
-        th[1].setForeground(txc);
-        th[1].setBounds(tbb.get(0)+l2p, tbb.get(1), 80, lineheight);
-        th[2] = new JLabel("# Played");
-        th[2].setForeground(txc);
-        th[2].setBounds(tbb.get(0)+l3p, tbb.get(1), 80, lineheight);
-        PA.add(th[0]);
-        PA.add(th[1]);
-        PA.add(th[2]);
-        tab = new JLabel[lc][3];
-        for (int ix=0;ix<lc;ix++)
-        {
-            JLabel[] cnt = tab[ix];
-            cnt[0] = new JLabel("###################################################<><>");  //DEBUG_PLACEHOLDERS
-            cnt[0].setBounds(tbb.get(0), tbb.get(1)+(lineheight*(ix+1)), l2p, lineheight);
-            cnt[0].setForeground(txc);
-            cnt[0].addMouseListener(this);
-            PA.add(cnt[0]);
-            cnt[1] = new JLabel("########>>>");
-            cnt[1].setBounds(tbb.get(0)+l2p, tbb.get(1)+(lineheight*(ix+1)), 80, lineheight);
-            cnt[1].setForeground(txc);
-            cnt[1].addMouseListener(this);
-            PA.add(cnt[1]);
-            cnt[2] = new JLabel("<<<########");
-            cnt[2].setBounds(tbb.get(0)+l3p, tbb.get(1)+(lineheight*(ix+1)), 80, lineheight);
-            cnt[2].setForeground(txc);
-            cnt[2].addMouseListener(this);
-            PA.add(cnt[2]);
-        }
-        
-        s = new JSlider(0,100);
-        ArrayList<Integer> sbb = (ArrayList<Integer>) ep.get("scrollbarstart");
-        s.setBounds(sbb.get(0), sbb.get(1), 20, tableheight);
-        HoloSliderUi ui = new HoloSliderUi(s,sliderknob);
-        ui.po=true;
-        s.setUI(ui);
-        s.setOpaque(false);
-        s.setOrientation(JSlider.VERTICAL);
-        s.setMinimum(0);
-        s.setMaximum(100);
-        s.setInverted(true);
-        s.addMouseMotionListener(this);
-        s.addMouseListener(this);
-        PA.add(s);
-        wrapper.add(PA);
-        PlayListEditAPI.setSortMode(md);
-    }
-    
-    private PlayListEditAPI.SortMode md = PlayListEditAPI.SortMode.NAME;
-    
-    public void reloadWorker()
-    {
-        selectedLine=-1;
-        PlayListEditAPI.setSortMode(md);
-        PlayListEditAPI.refreshKeyList();
-        titles=PlayListEditAPI.getTrackTitles();
-        s.setVisible(titles.length>lc);//deaktivieren wenn weniger zeilen als LC; mehr wenn aktiviert...
-        s.setMaximum(((titles.length-lc)<0?0:titles.length-lc));
-        s.setValue(0);//an anfang kalibrieren...
-        for (int i = 0; i < lc; i++)//kontrolliertes ausIxxen der tabelle zur initialisierung; man braucht keine Debugzeilen am ende wenn weniger Zeilen als LIneCount....
-        {
-            JLabel[] l = tab[i];
-            for (int j = 0; j < l.length; j++)
-            {
-                l[j].setText("");
-            }
-        }
-        for (int i = 0; i < titles.length; i++)
-        {
-            if(i<lc)
-            {
-            JLabel[] l = tab[i];
-            String t = titles[i];
-            l[0].setText(t);
-            l[1].setText(PlayListEditAPI.getTargetPlayCount(i)+"");
-            l[2].setText(PlayListEditAPI.getPlayCount(i)+"");
-            }
-            else
-            {
-                break;
-            }
-        }
-    }
-    
-    
-    
-    @Override
-    public void mouseDragged(MouseEvent e)
-    {
-        tickTable(s.getValue());
-    }
-    
-    public void tickTable(int bv)
-    {
-        for (int i = 0; i < lc; i++)
-        {
-            int ir = i+bv;
-            JLabel[] l = tab[i];
-            String t = titles[ir];
-            l[0].setText(t);
-            l[1].setText(PlayListEditAPI.getTargetPlayCount(ir)+"");
-            l[2].setText(PlayListEditAPI.getPlayCount(ir)+"");
-            if(selectedLine!=-1&&selectedLine==i+bv)
-            {
-                l[0].setForeground(selected);
-                l[1].setForeground(selected);
-                l[2].setForeground(selected);
-            }
-            else
-            {
-                l[0].setForeground(txc);
-                l[1].setForeground(txc);
-                l[2].setForeground(txc);
-            }
-        }
-        
-    }
-    //scrollbarstart -> obere linke ecke des sliders; Höhe = tableheight
-     //scrollbarknob
-    
-    public void tickGUI(int affectedButton,boolean state)
-    {
-        HashMap ep = sf.getElementPositions();
-        Graphics g = paintme.getGraphics();
-        ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));//WIXTIX!!!!
-        g.drawImage(background, 0, 0, null);
-        if(affectedButton==BUTTON_IXX_ID)
-        {
-            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_IXX");
-            if(state==STATE_HILIT)
-            {
-                g.drawImage(buttonIxxHilit, ixb.get(0), ixb.get(1), null);
-            }
-            else
-            {
-               g.drawImage(buttonIxxClicked, ixb.get(0), ixb.get(1), null);
-            }
-        }
-        if(affectedButton==BUTTON_MIN_ID)
-        {
-            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_min");
-            if(state==STATE_HILIT)
-            {
-                g.drawImage(buttonMinHilit, ixb.get(0), ixb.get(1), null);
-            }
-            else
-            {
-               g.drawImage(buttonMinClicked, ixb.get(0), ixb.get(1), null);
-            }
-        }
-        if(affectedButton==BUTTON_HIDE_ID)
-        {
-            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_hide");
-            if(state==STATE_HILIT)
-            {
-                g.drawImage(buttonHideHilit, ixb.get(0), ixb.get(1), null);
-            }
-            else
-            {
-               g.drawImage(buttonHideClicked, ixb.get(0), ixb.get(1), null);
-            }
-        }
-        if(affectedButton==BUTTON_RELOAD_ID)
-        {
-            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_reload");
-            if(state==STATE_HILIT)
-            {
-                g.drawImage(buttonReloadHilit, ixb.get(0), ixb.get(1), null);
-            }
-            else
-            {
-               g.drawImage(buttonReloadClicked, ixb.get(0), ixb.get(1), null);
-            }
-        }
-        if(affectedButton==BUTTON_FORCE_ID)
-        {
-            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_force");
-            if(state==STATE_HILIT)
-            {
-                g.drawImage(buttonForceHilit, ixb.get(0), ixb.get(1), null);
-            }
-            else
-            {
-               g.drawImage(buttonForceClicked, ixb.get(0), ixb.get(1), null);
-            }
-        }
-        wrapper.repaint();
-    }
-
-
-    public void processSelection(JLabel l)
-    {
-        for (int i = 0; i < tab.length; i++)
-        {
-            JLabel[] line = tab[i];
-            for (JLabel te : line)
-            {
-                if(te.equals(l))
-                {
-                    selectedLine=i+s.getValue();
-                    tickTable(s.getValue());
-                    return;
-                }
-            }
-        }
-    }
-    
-    
-    
-    private Image loadImageAux(String filename)
-    {
-        try
-        {
-            TFileInputStream f = new TFileInputStream(bdir + File.separator + filename);
-            Image i = ImageIO.read(f);
-            f.close();
-            return i;
-        }
-        catch (IOException ex)
-        {
-            ex.printStackTrace();
-        }
-        return null;
-    }
-
-    
-    
-    
-
-
-    @Override
-    public void mouseMoved(MouseEvent e)
-    {
-        Point p = e.getPoint();
-        if(buttonIxx.contains(p))
-        {
-            tickGUI(BUTTON_IXX_ID, STATE_HILIT);
-        }
-        else
-        {
-            if(buttonMin.contains(p))
-            {
-                 tickGUI(BUTTON_MIN_ID, STATE_HILIT);
-            }
-            else
-            {
-                if(buttonHide.contains(p))
-                {
-                     tickGUI(BUTTON_HIDE_ID, STATE_HILIT);
-                }
-                else
-                {
-                    if(buttonReload.contains(p))
-                    {
-                         tickGUI(BUTTON_RELOAD_ID, STATE_HILIT);
-                    }
-                    else
-                    {
-                        if(buttonForce.contains(p))
-                        {
-                            tickGUI(BUTTON_FORCE_ID, STATE_HILIT);
-                        }
-                        else
-                        {
-                            tickGUI(BUTTON_NONE_ID, STATE_HILIT);
-                        }
-                    }
-                }
-            }
-        }  
-    }
-    
-    Point pp = new Point();
-    
-    @Override
-    public void mouseClicked(MouseEvent e)
-    {
-        if(e.getSource()==s)
-        {
-            tickTable(s.getValue());
-            return;
-        }
-        if(e.getSource() instanceof JLabel)
-        {
-            processSelection((JLabel)e.getSource());
-            return;
-        }
-        pp=e.getPoint();
-        
-    }
-
-    @Override
-    public void mousePressed(MouseEvent e)
-    {
-        if(e.getSource()==s)
-        {
-            tickTable(s.getValue());
-            return;
-        }
-        pp=e.getPoint();
-        Point p = e.getPoint();
-        if((e.getButton()&MouseEvent.BUTTON2)!=0)
-        {
-            return; //hook für Kontextmenü :P
-        }
-        if(buttonIxx.contains(p))
-        {
-            tickGUI(BUTTON_IXX_ID, STATE_CLICKED);
-        }
-        else
-        {
-            if(buttonMin.contains(p))
-            {
-                 tickGUI(BUTTON_MIN_ID, STATE_CLICKED);
-            }
-            else
-            {
-                if(buttonHide.contains(p))
-                {
-                     tickGUI(BUTTON_HIDE_ID, STATE_CLICKED);
-                }
-                else
-                {
-                    if(buttonReload.contains(p))
-                    {
-                         tickGUI(BUTTON_RELOAD_ID, STATE_CLICKED);
-                    }
-                    else
-                    {
-                        if(buttonForce.contains(p))
-                        {
-                            tickGUI(BUTTON_FORCE_ID, STATE_CLICKED);
-                        }
-                        else
-                        {
-                            tickGUI(BUTTON_NONE_ID, STATE_CLICKED);
-                        }
-                    }
-                }
-            }
-        }
-    }
-    
-    @Override
-    public void setVisibleAux(boolean state)
-    {
-        reloadWorker();
-        wrapper.setVisible(state);
-    }
-    
-    
-    @Override
-    public void mouseReleased(MouseEvent e)
-    {
-        if(e.getSource() instanceof JLabel)
-        {
-            processSelection((JLabel)e.getSource());
-            return;
-        }
-
-        if((e.getButton()&MouseEvent.BUTTON2)!=0)
-        {
-            return; //hook für Kontextmenü :P
-        }
-        Point p = e.getPoint();
-        if(buttonIxx.contains(p)&&buttonIxx.contains(pp))
-        {
-            if(IZPLApi.isNEwGUIMode())
-            {
-                if(Tools.dlg(true,"Wirklich beenden", "","Ja","Nein"))
-                {
-                    System.exit(0);
-                }
-            }
-            else
-            {
-                setVisibleAux(false);
-            }
-        }
-        else
-        {
-            if(buttonMin.contains(p)&&buttonMin.contains(pp))
-            {
-                if(wrapper instanceof JFrame)
-                    ((JFrame)wrapper).setState(JFrame.ICONIFIED);
-                else
-                    wrapper.setVisible(false);
-            }
-            else
-            {
-                if(buttonHide.contains(p)&&buttonHide.contains(pp))
-                {
-                    if(wrapper instanceof JFrame)
-                    ((JFrame)wrapper).setState(JFrame.ICONIFIED);
-                    else
-                        wrapper.setVisible(false);
-                    }
-                else
-                {
-                    if(buttonReload.contains(p)&&buttonReload.contains(pp))
-                    {
-                        if(e.isShiftDown())
-                        {  
-                            if((e.getModifiers()& ActionEvent.SHIFT_MASK)!=0)
-                            {
-                                PlayListEditAPI.reloadList();
-                            }
-                            
-                        }
-                        reloadWorker();
-                    }
-                    else
-                    {
-                        if(buttonForce.contains(p)&&buttonForce.contains(pp))
-                        {
-                            if(selectedLine!=-1)
-                            {
-                                PlayListEditAPI.forceElement(selectedLine);
-                            }
-                        }
-                        else
-                        {
-
-                        }
-                    }
-                }
-            }
-            
-        }
-    }
-
-    @Override
-    public void mouseEntered(MouseEvent e)
-    {
-        
-    }
-
-    @Override
-    public void mouseExited(MouseEvent e)
-    {
-        
-    }
-    public Window getWrapper()
-    {
-        return wrapper;
-    }
-    
-    @Override
-    public void disableDraggability()
-    {
-        if(!unmoveable)
-        {
-            m.deregisterComponent(titlebar);
-            unmoveable=true;
-        }
-    }
-    
-}
-
-
-/**
- * Pfad zu skins: iZplaylist-dir/skins/*.iZskin; 
- * 
- * Definition Skin-metadata
- * //namen der objekte;
- * //backgroundlayer -> basis-oberfläche;GFX
- * //tablestart -> obere linke ecke der labels
- * //tablewidth -> breite der labels
- * //tableheight -> höhe der tabelle
- * //scrollbarstart -> obere linke ecke des sliders; Höhe = tableheight
- * //scrollbarknob -> nippel des sliders;GFX
- * //lineheight -> höhe einer einzelnen Zeile -> bestimmt Zeilenzahl
- * //mode=_clicked/_hilit
- * //button_IXX<_mode> -> schließenschaltfläche;GFX
- * //button_min<_mode> -> Minimierenbutton;GFX
- * //button_reload<_mode> -> neuladen-button;GFX
- * //button_force<_mode> -> erzwingen-button;GFX
- * //button_hide<_mode> -> ausblenden-button;GFX
- * //button_<buttonname> -> basepoint des buttons
- * 
- * //button_<buttonname>_point_N = Polygonpunkt der Selektierungszone relativ zu seinem nullpunkt...
- * 
- * 
- */
+/*
+ * Copyright (C) 2015 iZc
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.nplusc.izc.iZpl.GUI;
+
+import de.nplusc.izc.iZpl.API.PlayListEditAPI;
+import com.sun.awt.AWTUtilities;
+import de.nplusc.izc.iZpl.API.IZPLApi;
+import de.nplusc.izc.iZpl.API.shared.InvalidPlayListFileException;
+import de.nplusc.izc.tools.UiToolz.ComponentMover;
+import de.nplusc.izc.tools.UiToolz.HoloJPanel;
+import de.nplusc.izc.tools.UiToolz.HoloSliderUi;
+import de.nplusc.izc.tools.UiToolz.IZSkinFile;
+import de.nplusc.izc.tools.baseTools.Messagers;
+import de.nplusc.izc.tools.baseTools.Tools;
+import de.schlichtherle.truezip.file.TFileInputStream;
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import javax.imageio.ImageIO;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+/**
+ *
+ * @author LH
+ */
+public class PlayListManagingSkinnable extends JPanel implements MouseMotionListener , MouseListener,PlayListManagingCommon
+{
+    private static final Logger l = LogManager.getLogger();
+    
+    public static final int BUTTON_NONE_ID=0;
+    public static final int BUTTON_IXX_ID=1;
+    public static final int BUTTON_MIN_ID=2;
+    public static final int BUTTON_HIDE_ID=3;
+    public static final int BUTTON_RELOAD_ID=4;
+    public static final int BUTTON_FORCE_ID=5;
+    
+    public static final boolean STATE_HILIT=false;
+    public static final boolean STATE_CLICKED=!STATE_HILIT;
+    public static final Color TransBgColor = new Color(0, 0, 0, 0);
+    
+    private final String bdir;
+    private final IZSkinFile sf;
+    private final int h,w;
+    private final ComponentMover m;
+    private final JSlider s;
+    private final Color txc;
+    private final Color selected;
+    private int textColorR,selectedColorR;
+    private String[] titles;
+    private final JPanel titlebar;
+    private final Image paintme,background,buttonIxxClicked,buttonIxxHilit,buttonMinClicked,buttonMinHilit,buttonHideClicked,buttonHideHilit,
+                    buttonReloadHilit,buttonReloadClicked,buttonForceClicked,buttonForceHilit,sliderknob;
+    private final HoloJPanel PA;
+    //definieren die heißen zonen....
+    private final Polygon buttonIxx,buttonMin,buttonHide,buttonReload,buttonForce;
+    private int tablewidth=500,tableheight=500,lineheight=15;//defaultwerte wenn exception fliegt
+    //private final int defaultlc=0x000000,hilitcolor=0xffff00,selected=0xff7700;
+    private final int lc;//dynamish generiert im konstruktor; lazyness...
+    private int titlebarwidth;
+    JLabel[] th;//datenjonglage die 2.
+    private final Window wrapper;
+    private int selectedLine=-1;
+    private boolean unmoveable=false;
+    
+    
+    JLabel[][] tab;//datenjonglage...
+    @SuppressWarnings("empty-statement")
+    public PlayListManagingSkinnable(Window wrapper,String skinPath,IZSkinFile sfp)
+    {
+        if(wrapper instanceof JFrame)
+        {
+            wrapper.setIconImage(IZPLApi.getProgramIcon());
+        }
+        this.wrapper=wrapper;
+        bdir=skinPath;
+        sf=sfp;
+        @SuppressWarnings("null")
+        HashMap<String,String> ed=sf.getElementData();
+        HashMap<String,ArrayList<Integer>> ep = sf.getElementPositions();
+        
+        //separate exceptions sind gewollt um mitzuteilen welcher key fail'd
+        try{
+            tablewidth = Integer.valueOf(ed.get("tablewidth"));
+        }
+        catch(NumberFormatException lickme)
+        {
+            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für tablewidth");
+            IZPLApi.quickQuitWithoutSaving();
+        }
+        try{
+            titlebarwidth = Integer.valueOf(ed.get("titlebarwidth"));
+        }
+        catch(NumberFormatException lickme)
+        {
+            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für titlebarwidth");
+            IZPLApi.quickQuitWithoutSaving();
+        }
+                try{
+            titlebarwidth = Integer.valueOf(ed.get("titlebarwidth"));
+        }
+        catch(NumberFormatException lickme)
+        {
+            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für titlebarwidth");
+            IZPLApi.quickQuitWithoutSaving();
+        }
+        try{
+           textColorR = Integer.valueOf(ed.get("textcolor").substring(2),16);
+        }
+        catch(NumberFormatException lickme)
+        {
+            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für tableheight");
+            IZPLApi.quickQuitWithoutSaving();
+        }
+        try{
+           selectedColorR = Integer.valueOf(ed.get("textcolormarked").substring(2),16);
+        }
+        catch(NumberFormatException lickme)
+        {
+            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für tableheight");
+            IZPLApi.quickQuitWithoutSaving();
+        }
+        try{
+            lineheight = Integer.valueOf(ed.get("lineheight"));
+        }
+        catch(NumberFormatException lickme)
+        {
+            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für lineheight");
+            IZPLApi.quickQuitWithoutSaving();
+        }
+        if(wrapper instanceof JFrame)
+        {
+        ((JFrame)wrapper).setUndecorated(true);
+        }
+        else if(wrapper instanceof JDialog)
+        {
+        ((JDialog)wrapper).setUndecorated(true);
+        }
+        else
+        {
+            throw new UnsupportedOperationException("Only JFrame or JDialog supported");
+        }
+        boolean tp = AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT);
+        if(tp)
+        {
+            AWTUtilities.setWindowOpaque(wrapper, false);//freischalten von irregularShapes
+            //AWTUtilities.
+        }
+        background = loadImageAux(ed.get("backgroundlayer"));
+        paintme = loadImageAux(ed.get("backgroundlayer"));//background ist default deshalb doppeltgemoppelt; auf paintme wird später rumgepinselt
+        buttonIxxHilit = loadImageAux(ed.get("button_IXX_hilit"));
+        buttonIxxClicked = loadImageAux(ed.get("button_IXX_clicked"));
+        buttonMinHilit = loadImageAux(ed.get("button_min_hilit"));;
+        buttonMinClicked = loadImageAux(ed.get("button_min_clicked"));
+        buttonHideClicked = loadImageAux(ed.get("button_hide_clicked"));
+        buttonHideHilit = loadImageAux(ed.get("button_hide_hilit"));
+        buttonReloadClicked = loadImageAux(ed.get("button_reload_clicked"));;
+        buttonReloadHilit = loadImageAux(ed.get("button_reload_hilit"));
+        buttonForceClicked = loadImageAux(ed.get("button_force_clicked"));
+        buttonForceHilit = loadImageAux(ed.get("button_force_hilit"));
+        sliderknob=loadImageAux(ed.get("scrollbarknob"));
+        
+        
+        while(background.getHeight(null)<=0);  //absicern dass image geladen...
+        while(paintme.getHeight(null)<=0);  //absicern dass image geladen...
+        h = background.getHeight(null);
+        w = background.getWidth(null);
+        setSize(w, h);
+        wrapper.setSize(w, h);
+        PA= new HoloJPanel();
+        PA.setSize(w,h);
+        PA.setOpaque(false);
+        setOpaque(false);
+        //int[] ixb = ep.get("button_IXX");
+        //paintme.getGraphics().drawImage(buttonIxxHilit, ixb[0], ixb[1], null);
+        PA.setdrawIMG(paintme);
+        add(PA);
+        l.info("skindim="+w+"|"+h);
+        
+        Container cp = null;
+        if(wrapper instanceof JFrame)
+        {
+            cp = ((JFrame)wrapper).getContentPane();
+        
+        }
+        else
+        {
+            cp=((JDialog)wrapper).getContentPane();
+        }
+        cp.setLayout(null);
+        while(buttonIxxHilit.getHeight(null)<=0);
+        while(buttonIxxClicked.getHeight(null)<=0);
+        while(buttonMinHilit.getHeight(null)<=0);
+        while(buttonMinClicked.getHeight(null)<=0);
+        while(buttonHideClicked.getHeight(null)<=0);
+        while(buttonHideHilit.getHeight(null)<=0);
+        while(buttonReloadClicked.getHeight(null)<=0);
+        while(buttonReloadHilit.getHeight(null)<=0);
+        while(buttonForceClicked.getHeight(null)<=0);
+        while(buttonForceHilit.getHeight(null)<=0);
+        while(sliderknob.getHeight(null)<=0); //absicern dass image geladen...
+        PA.addMouseListener(this);
+        PA.addMouseMotionListener(this);
+        addMouseListener(this);
+        addMouseMotionListener(this);
+        HoloJPanel p = new HoloJPanel();
+        PA.setLayout(null);
+        //BufferedImage b = new BufferedImage(700, 30, BufferedImage.TYPE_4BYTE_ABGR);
+        //b.getGraphics().setColor(Color.BLACK);
+        //b.getGraphics().fillRect(0, 0, 700, 30);
+        p.setdrawIMG(background);
+        
+        p.setSize(titlebarwidth,30);
+        titlebar=p;
+        PA.add(p);
+        m=new ComponentMover(wrapper.getClass());
+        m.registerComponent(p);
+        //ermöglichen der buttonerkennung...
+        boolean buttondetected = true;
+        buttonIxx = new Polygon();
+        int i = 1;
+        while (buttondetected)
+        {
+            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_IXX");
+            List<Integer> data = (List<Integer>) ep.get("button_IXX_point_" + i);
+            buttonIxx.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
+            i++;
+            buttondetected = ep.containsKey("button_IXX_point_" + i);
+        }
+        buttondetected = true;
+        buttonMin = new Polygon();
+        i = 1;
+        while (buttondetected)
+        {
+            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_min");
+            List<Integer> data = (List<Integer>) ep.get("button_min_point_" + i);
+            buttonMin.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
+            i++;
+            buttondetected = ep.containsKey("button_min_point_" + i);
+        }
+        buttondetected = true;
+        buttonHide = new Polygon();
+        i = 1;
+        while (buttondetected)
+        {
+            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_hide");
+            List<Integer> data = (List<Integer>) ep.get("button_hide_point_" + i);
+            buttonHide.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
+            i++;
+            buttondetected = ep.containsKey("button_hide_point_" + i);
+        }
+        buttondetected = true;
+        buttonForce = new Polygon();
+        i = 1;
+        while (buttondetected)
+        {
+            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_force");
+            List<Integer> data = (List<Integer>) ep.get("button_force_point_" + i);
+            buttonForce.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
+            i++;
+            buttondetected = ep.containsKey("button_force_point_" + i);
+        }
+        buttondetected = true;
+        buttonReload = new Polygon();
+        i = 1;
+        while (buttondetected)
+        {
+            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_reload");
+            List<Integer> data = (List<Integer>) ep.get("button_reload_point_" + i);
+            buttonReload.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
+            i++;
+            buttondetected = ep.containsKey("button_reload_point_" + i);
+        }
+        
+        txc=new Color(textColorR);
+        selected=new Color(selectedColorR);
+        
+        //generate_table
+        int l2p=tablewidth-160,l3p=tablewidth-80;
+        PA.setLayout(null);
+        lc = tableheight/lineheight-1;//oberste zeile=header
+        ArrayList<Integer> tbb = (ArrayList<Integer>) ep.get("tablestart");
+        l.trace("tw(l2p,l3p),th,lc,lh|tbb[0],tbb[1]=>"+tablewidth+"("+l2p+","+l3p+"),"+tableheight+","+lc+","+lineheight+"|"+tbb.get(0)+","+tbb.get(1));
+        th = new JLabel[3];
+        th[0] = new JLabel("Element-Titel");
+        th[0].setForeground(txc);
+        th[0].setBounds(tbb.get(0), tbb.get(1), l2p, lineheight);
+        th[1] = new JLabel("# to play");
+        th[1].setForeground(txc);
+        th[1].setBounds(tbb.get(0)+l2p, tbb.get(1), 80, lineheight);
+        th[2] = new JLabel("# Played");
+        th[2].setForeground(txc);
+        th[2].setBounds(tbb.get(0)+l3p, tbb.get(1), 80, lineheight);
+        PA.add(th[0]);
+        PA.add(th[1]);
+        PA.add(th[2]);
+        tab = new JLabel[lc][3];
+        for (int ix=0;ix<lc;ix++)
+        {
+            JLabel[] cnt = tab[ix];
+            cnt[0] = new JLabel("###################################################<><>");  //DEBUG_PLACEHOLDERS
+            cnt[0].setBounds(tbb.get(0), tbb.get(1)+(lineheight*(ix+1)), l2p, lineheight);
+            cnt[0].setForeground(txc);
+            cnt[0].addMouseListener(this);
+            PA.add(cnt[0]);
+            cnt[1] = new JLabel("########>>>");
+            cnt[1].setBounds(tbb.get(0)+l2p, tbb.get(1)+(lineheight*(ix+1)), 80, lineheight);
+            cnt[1].setForeground(txc);
+            cnt[1].addMouseListener(this);
+            PA.add(cnt[1]);
+            cnt[2] = new JLabel("<<<########");
+            cnt[2].setBounds(tbb.get(0)+l3p, tbb.get(1)+(lineheight*(ix+1)), 80, lineheight);
+            cnt[2].setForeground(txc);
+            cnt[2].addMouseListener(this);
+            PA.add(cnt[2]);
+        }
+        
+        s = new JSlider(0,100);
+        ArrayList<Integer> sbb = (ArrayList<Integer>) ep.get("scrollbarstart");
+        s.setBounds(sbb.get(0), sbb.get(1), 20, tableheight);
+        HoloSliderUi ui = new HoloSliderUi(s,sliderknob);
+        ui.po=true;
+        s.setUI(ui);
+        s.setOpaque(false);
+        s.setOrientation(JSlider.VERTICAL);
+        s.setMinimum(0);
+        s.setMaximum(100);
+        s.setInverted(true);
+        s.addMouseMotionListener(this);
+        s.addMouseListener(this);
+        PA.add(s);
+        wrapper.add(PA);
+        PlayListEditAPI.setSortMode(md);
+    }
+    
+    private PlayListEditAPI.SortMode md = PlayListEditAPI.SortMode.NAME;
+    
+    public void reloadWorker()
+    {
+        reloadWorkerInternal(false);
+    }
+    
+    private void reloadWorkerInternal(boolean recovery)
+    {
+        try
+        {
+            selectedLine=-1;
+            PlayListEditAPI.setSortMode(md);
+            PlayListEditAPI.refreshKeyList();
+            titles=PlayListEditAPI.getTrackTitles();
+            s.setVisible(titles.length>lc);//deaktivieren wenn weniger zeilen als LC; mehr wenn aktiviert...
+            s.setMaximum(((titles.length-lc)<0?0:titles.length-lc));
+            s.setValue(0);//an anfang kalibrieren...
+            for (int i = 0; i < lc; i++)//kontrolliertes ausIxxen der tabelle zur initialisierung; man braucht keine Debugzeilen am ende wenn weniger Zeilen als LIneCount....
+            {
+                JLabel[] l = tab[i];
+                for (int j = 0; j < l.length; j++)
+                {
+                    l[j].setText("");
+                }
+            }
+            for (int i = 0; i < titles.length; i++)
+            {
+                if(i<lc)
+                {
+                JLabel[] l = tab[i];
+                String t = titles[i];
+                l[0].setText(t);
+                l[1].setText(PlayListEditAPI.getTargetPlayCount(i)+"");
+                l[2].setText(PlayListEditAPI.getPlayCount(i)+"");
+                }
+                else
+                {
+                    break;
+                }
+            }
+        }
+        catch(InvalidPlayListFileException e)
+        {
+            if(recovery)
+            {
+                l.error("Serious statefile corruption detected");
+                IZPLApi.quickQuitWithoutSaving();
+            }
+            //reloading data from disk and flushing internal references when the resume state got corrupted from a encoding change
+            PlayListEditAPI.reloadList();
+            reloadWorkerInternal(recovery);
+        }
+    }
+    
+    @Override
+    public void mouseDragged(MouseEvent e)
+    {
+        tickTable(s.getValue());
+    }
+    
+    public void tickTable(int bv)
+    {
+        for (int i = 0; i < lc; i++)
+        {
+            int ir = i+bv;
+            JLabel[] l = tab[i];
+            String t = titles[ir];
+            l[0].setText(t);
+            l[1].setText(PlayListEditAPI.getTargetPlayCount(ir)+"");
+            l[2].setText(PlayListEditAPI.getPlayCount(ir)+"");
+            if(selectedLine!=-1&&selectedLine==i+bv)
+            {
+                l[0].setForeground(selected);
+                l[1].setForeground(selected);
+                l[2].setForeground(selected);
+            }
+            else
+            {
+                l[0].setForeground(txc);
+                l[1].setForeground(txc);
+                l[2].setForeground(txc);
+            }
+        }
+        
+    }
+    //scrollbarstart -> obere linke ecke des sliders; Höhe = tableheight
+     //scrollbarknob
+    
+    public void tickGUI(int affectedButton,boolean state)
+    {
+        HashMap ep = sf.getElementPositions();
+        Graphics g = paintme.getGraphics();
+        ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));//WIXTIX!!!!
+        g.drawImage(background, 0, 0, null);
+        if(affectedButton==BUTTON_IXX_ID)
+        {
+            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_IXX");
+            if(state==STATE_HILIT)
+            {
+                g.drawImage(buttonIxxHilit, ixb.get(0), ixb.get(1), null);
+            }
+            else
+            {
+               g.drawImage(buttonIxxClicked, ixb.get(0), ixb.get(1), null);
+            }
+        }
+        if(affectedButton==BUTTON_MIN_ID)
+        {
+            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_min");
+            if(state==STATE_HILIT)
+            {
+                g.drawImage(buttonMinHilit, ixb.get(0), ixb.get(1), null);
+            }
+            else
+            {
+               g.drawImage(buttonMinClicked, ixb.get(0), ixb.get(1), null);
+            }
+        }
+        if(affectedButton==BUTTON_HIDE_ID)
+        {
+            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_hide");
+            if(state==STATE_HILIT)
+            {
+                g.drawImage(buttonHideHilit, ixb.get(0), ixb.get(1), null);
+            }
+            else
+            {
+               g.drawImage(buttonHideClicked, ixb.get(0), ixb.get(1), null);
+            }
+        }
+        if(affectedButton==BUTTON_RELOAD_ID)
+        {
+            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_reload");
+            if(state==STATE_HILIT)
+            {
+                g.drawImage(buttonReloadHilit, ixb.get(0), ixb.get(1), null);
+            }
+            else
+            {
+               g.drawImage(buttonReloadClicked, ixb.get(0), ixb.get(1), null);
+            }
+        }
+        if(affectedButton==BUTTON_FORCE_ID)
+        {
+            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_force");
+            if(state==STATE_HILIT)
+            {
+                g.drawImage(buttonForceHilit, ixb.get(0), ixb.get(1), null);
+            }
+            else
+            {
+               g.drawImage(buttonForceClicked, ixb.get(0), ixb.get(1), null);
+            }
+        }
+        wrapper.repaint();
+    }
+
+
+    public void processSelection(JLabel l)
+    {
+        for (int i = 0; i < tab.length; i++)
+        {
+            JLabel[] line = tab[i];
+            for (JLabel te : line)
+            {
+                if(te.equals(l))
+                {
+                    selectedLine=i+s.getValue();
+                    tickTable(s.getValue());
+                    return;
+                }
+            }
+        }
+    }
+    
+    
+    
+    private Image loadImageAux(String filename)
+    {
+        try
+        {
+            TFileInputStream f = new TFileInputStream(bdir + File.separator + filename);
+            Image i = ImageIO.read(f);
+            f.close();
+            return i;
+        }
+        catch (IOException ex)
+        {
+            ex.printStackTrace();
+        }
+        return null;
+    }
+
+    
+    
+    
+
+
+    @Override
+    public void mouseMoved(MouseEvent e)
+    {
+        Point p = e.getPoint();
+        if(buttonIxx.contains(p))
+        {
+            tickGUI(BUTTON_IXX_ID, STATE_HILIT);
+        }
+        else
+        {
+            if(buttonMin.contains(p))
+            {
+                 tickGUI(BUTTON_MIN_ID, STATE_HILIT);
+            }
+            else
+            {
+                if(buttonHide.contains(p))
+                {
+                     tickGUI(BUTTON_HIDE_ID, STATE_HILIT);
+                }
+                else
+                {
+                    if(buttonReload.contains(p))
+                    {
+                         tickGUI(BUTTON_RELOAD_ID, STATE_HILIT);
+                    }
+                    else
+                    {
+                        if(buttonForce.contains(p))
+                        {
+                            tickGUI(BUTTON_FORCE_ID, STATE_HILIT);
+                        }
+                        else
+                        {
+                            tickGUI(BUTTON_NONE_ID, STATE_HILIT);
+                        }
+                    }
+                }
+            }
+        }  
+    }
+    
+    Point pp = new Point();
+    
+    @Override
+    public void mouseClicked(MouseEvent e)
+    {
+        if(e.getSource()==s)
+        {
+            tickTable(s.getValue());
+            return;
+        }
+        if(e.getSource() instanceof JLabel)
+        {
+            processSelection((JLabel)e.getSource());
+            return;
+        }
+        pp=e.getPoint();
+        
+    }
+
+    @Override
+    public void mousePressed(MouseEvent e)
+    {
+        if(e.getSource()==s)
+        {
+            tickTable(s.getValue());
+            return;
+        }
+        pp=e.getPoint();
+        Point p = e.getPoint();
+        if((e.getButton()&MouseEvent.BUTTON2)!=0)
+        {
+            return; //hook für Kontextmenü :P
+        }
+        if(buttonIxx.contains(p))
+        {
+            tickGUI(BUTTON_IXX_ID, STATE_CLICKED);
+        }
+        else
+        {
+            if(buttonMin.contains(p))
+            {
+                 tickGUI(BUTTON_MIN_ID, STATE_CLICKED);
+            }
+            else
+            {
+                if(buttonHide.contains(p))
+                {
+                     tickGUI(BUTTON_HIDE_ID, STATE_CLICKED);
+                }
+                else
+                {
+                    if(buttonReload.contains(p))
+                    {
+                         tickGUI(BUTTON_RELOAD_ID, STATE_CLICKED);
+                    }
+                    else
+                    {
+                        if(buttonForce.contains(p))
+                        {
+                            tickGUI(BUTTON_FORCE_ID, STATE_CLICKED);
+                        }
+                        else
+                        {
+                            tickGUI(BUTTON_NONE_ID, STATE_CLICKED);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    @Override
+    public void setVisibleAux(boolean state)
+    {
+        reloadWorker();
+        wrapper.setVisible(state);
+    }
+    
+    
+    @Override
+    public void mouseReleased(MouseEvent e)
+    {
+        if(e.getSource() instanceof JLabel)
+        {
+            processSelection((JLabel)e.getSource());
+            return;
+        }
+
+        if((e.getButton()&MouseEvent.BUTTON2)!=0)
+        {
+            return; //hook für Kontextmenü :P
+        }
+        Point p = e.getPoint();
+        if(buttonIxx.contains(p)&&buttonIxx.contains(pp))
+        {
+            if(IZPLApi.isNEwGUIMode())
+            {
+                if(Tools.dlg(true,"Wirklich beenden", "","Ja","Nein"))
+                {
+                    System.exit(0);
+                }
+            }
+            else
+            {
+                setVisibleAux(false);
+            }
+        }
+        else
+        {
+            if(buttonMin.contains(p)&&buttonMin.contains(pp))
+            {
+                if(wrapper instanceof JFrame)
+                    ((JFrame)wrapper).setState(JFrame.ICONIFIED);
+                else
+                    wrapper.setVisible(false);
+            }
+            else
+            {
+                if(buttonHide.contains(p)&&buttonHide.contains(pp))
+                {
+                    if(wrapper instanceof JFrame)
+                    ((JFrame)wrapper).setState(JFrame.ICONIFIED);
+                    else
+                        wrapper.setVisible(false);
+                    }
+                else
+                {
+                    if(buttonReload.contains(p)&&buttonReload.contains(pp))
+                    {
+                        if(e.isShiftDown())
+                        {  
+                            if((e.getModifiers()& ActionEvent.SHIFT_MASK)!=0)
+                            {
+                                PlayListEditAPI.reloadList();
+                            }
+                            
+                        }
+                        reloadWorker();
+                    }
+                    else
+                    {
+                        if(buttonForce.contains(p)&&buttonForce.contains(pp))
+                        {
+                            if(selectedLine!=-1)
+                            {
+                                PlayListEditAPI.forceElement(selectedLine);
+                            }
+                        }
+                        else
+                        {
+
+                        }
+                    }
+                }
+            }
+            
+        }
+    }
+
+    @Override
+    public void mouseEntered(MouseEvent e)
+    {
+        
+    }
+
+    @Override
+    public void mouseExited(MouseEvent e)
+    {
+        
+    }
+    public Window getWrapper()
+    {
+        return wrapper;
+    }
+    
+    @Override
+    public void disableDraggability()
+    {
+        if(!unmoveable)
+        {
+            m.deregisterComponent(titlebar);
+            unmoveable=true;
+        }
+    }
+    
+}
+
+
+/**
+ * Pfad zu skins: iZplaylist-dir/skins/*.iZskin; 
+ * 
+ * Definition Skin-metadata
+ * //namen der objekte;
+ * //backgroundlayer -> basis-oberfläche;GFX
+ * //tablestart -> obere linke ecke der labels
+ * //tablewidth -> breite der labels
+ * //tableheight -> höhe der tabelle
+ * //scrollbarstart -> obere linke ecke des sliders; Höhe = tableheight
+ * //scrollbarknob -> nippel des sliders;GFX
+ * //lineheight -> höhe einer einzelnen Zeile -> bestimmt Zeilenzahl
+ * //mode=_clicked/_hilit
+ * //button_IXX<_mode> -> schließenschaltfläche;GFX
+ * //button_min<_mode> -> Minimierenbutton;GFX
+ * //button_reload<_mode> -> neuladen-button;GFX
+ * //button_force<_mode> -> erzwingen-button;GFX
+ * //button_hide<_mode> -> ausblenden-button;GFX
+ * //button_<buttonname> -> basepoint des buttons
+ * 
+ * //button_<buttonname>_point_N = Polygonpunkt der Selektierungszone relativ zu seinem nullpunkt...
+ * 
+ * 
+ */