/** * MainPanel * * @author pquiring * * Date : Feb 8, 2012 * */ import javax.swing.*; import javax.swing.filechooser.*; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.font.*; import java.io.*; import java.util.*; import javaforce.*; import javaforce.gl.*; public class MainPanel extends javax.swing.JPanel implements MouseListener, MouseMotionListener, KeyListener, KeyEventDispatcher, ActionListener { public static String version = "0.21"; /** * Creates new form PaintPanel */ public MainPanel(JFrame frame, JApplet applet) { try { this.frame = frame; PaintCanvas.mainPanel = this; Border.panel = this; initComponents(); setLayout(new PanelLayout()); //can't make netbeans work properly addTab("untitled"); updateClr(foreColor, foreClr); updateClr(backColor, backClr); selBox.setSelected(true); javax.swing.Timer timer = new javax.swing.Timer(250, this); timer.start(); KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); selBox.doClick(); currentPath = JF.getUserPath() + "/Pictures"; thresholdSliderStateChanged(null); alphaSliderStateChanged(null); paintMode.setMaximumRowCount(paintMode.getItemCount()); //default is 8 rotateImg = new JFImage(); rotateImg.load(this.getClass().getResourceAsStream("rotate.png")); pixel = new JFImage(1,1); } catch (Exception e) { e.printStackTrace(); } } /** * 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() { group = new javax.swing.ButtonGroup(); toolbar1 = new javax.swing.JToolBar(); selBox = new javax.swing.JToggleButton(); fill = new javax.swing.JToggleButton(); pickColor = new javax.swing.JToggleButton(); pencil = new javax.swing.JToggleButton(); text = new javax.swing.JToggleButton(); curve = new javax.swing.JToggleButton(); line = new javax.swing.JToggleButton(); box = new javax.swing.JToggleButton(); circle = new javax.swing.JToggleButton(); sub = new javax.swing.JToggleButton(); jLabel3 = new javax.swing.JLabel(); rotateCW = new javax.swing.JButton(); rotateCCW = new javax.swing.JButton(); flipVert = new javax.swing.JButton(); flipHorz = new javax.swing.JButton(); scaleSize = new javax.swing.JButton(); jLabel4 = new javax.swing.JLabel(); fillMode = new javax.swing.JToggleButton(); fillAlpha = new javax.swing.JToggleButton(); fillEdge = new javax.swing.JToggleButton(); round = new javax.swing.JToggleButton(); selkeyclr = new javax.swing.JToggleButton(); jLabel5 = new javax.swing.JLabel(); selectFont = new javax.swing.JButton(); changeSize = new javax.swing.JButton(); backswap = new javax.swing.JButton(); toolbar2 = new javax.swing.JToolBar(); foreColor = new javax.swing.JButton(); swap = new javax.swing.JButton(); backColor = new javax.swing.JButton(); width = new javax.swing.JComboBox(); paintMode = new javax.swing.JComboBox(); colorLayer = new javax.swing.JComboBox(); layersButton = new javax.swing.JButton(); toolbar3 = new javax.swing.JToolBar(); jLabel1 = new javax.swing.JLabel(); threshold = new javax.swing.JLabel(); thresholdSlider = new javax.swing.JSlider(); jLabel2 = new javax.swing.JLabel(); alpha = new javax.swing.JLabel(); alphaSlider = new javax.swing.JSlider(); jLabel6 = new javax.swing.JLabel(); zoom = new javax.swing.JSlider(); zoomText = new javax.swing.JLabel(); tabs = new javax.swing.JTabbedPane(); status = new javax.swing.JTextField(); toolbar1.setFloatable(false); toolbar1.setRollover(true); group.add(selBox); selBox.setIcon(new javax.swing.ImageIcon(getClass().getResource("/selbox.png"))); // NOI18N selBox.setToolTipText("Selection Box"); selBox.setFocusable(false); selBox.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); selBox.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); selBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { selBoxActionPerformed(evt); } }); toolbar1.add(selBox); group.add(fill); fill.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fill.png"))); // NOI18N fill.setToolTipText("Fill (uses threshold)"); fill.setFocusable(false); fill.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); fill.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); fill.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { fillActionPerformed(evt); } }); toolbar1.add(fill); group.add(pickColor); pickColor.setIcon(new javax.swing.ImageIcon(getClass().getResource("/pickcolor.png"))); // NOI18N pickColor.setToolTipText("Pick Color"); pickColor.setFocusable(false); pickColor.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); pickColor.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); pickColor.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { pickColorActionPerformed(evt); } }); toolbar1.add(pickColor); group.add(pencil); pencil.setIcon(new javax.swing.ImageIcon(getClass().getResource("/pencil.png"))); // NOI18N pencil.setToolTipText("Pencil"); pencil.setFocusable(false); pencil.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); pencil.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); pencil.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { pencilActionPerformed(evt); } }); toolbar1.add(pencil); group.add(text); text.setIcon(new javax.swing.ImageIcon(getClass().getResource("/text.png"))); // NOI18N text.setToolTipText("Text"); text.setFocusable(false); text.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); text.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); text.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { textActionPerformed(evt); } }); toolbar1.add(text); group.add(curve); curve.setIcon(new javax.swing.ImageIcon(getClass().getResource("/curve.png"))); // NOI18N curve.setToolTipText("Curve"); curve.setFocusable(false); curve.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); curve.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); curve.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { curveActionPerformed(evt); } }); toolbar1.add(curve); group.add(line); line.setIcon(new javax.swing.ImageIcon(getClass().getResource("/line.png"))); // NOI18N line.setToolTipText("Line"); line.setFocusable(false); line.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); line.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); line.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { lineActionPerformed(evt); } }); toolbar1.add(line); group.add(box); box.setIcon(new javax.swing.ImageIcon(getClass().getResource("/box.png"))); // NOI18N box.setToolTipText("Box"); box.setFocusable(false); box.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); box.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); box.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { boxActionPerformed(evt); } }); toolbar1.add(box); group.add(circle); circle.setIcon(new javax.swing.ImageIcon(getClass().getResource("/circle.png"))); // NOI18N circle.setToolTipText("Circle"); circle.setFocusable(false); circle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); circle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); circle.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { circleActionPerformed(evt); } }); toolbar1.add(circle); group.add(sub); sub.setIcon(new javax.swing.ImageIcon(getClass().getResource("/sub.png"))); // NOI18N sub.setToolTipText("Substitute Box - Changes backColor to foreColor within drawn Box (uses threshold)"); sub.setFocusable(false); sub.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); sub.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); sub.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { subActionPerformed(evt); } }); toolbar1.add(sub); jLabel3.setText(":"); toolbar1.add(jLabel3); rotateCW.setIcon(new javax.swing.ImageIcon(getClass().getResource("/rotatecw.png"))); // NOI18N rotateCW.setToolTipText("Rotate CW"); rotateCW.setFocusable(false); rotateCW.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); rotateCW.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); rotateCW.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { rotateCWActionPerformed(evt); } }); toolbar1.add(rotateCW); rotateCCW.setIcon(new javax.swing.ImageIcon(getClass().getResource("/rotateccw.png"))); // NOI18N rotateCCW.setToolTipText("Rotate CCW"); rotateCCW.setFocusable(false); rotateCCW.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); rotateCCW.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); rotateCCW.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { rotateCCWActionPerformed(evt); } }); toolbar1.add(rotateCCW); flipVert.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flipvert.png"))); // NOI18N flipVert.setToolTipText("Flip Vertical"); flipVert.setFocusable(false); flipVert.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); flipVert.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); flipVert.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { flipVertActionPerformed(evt); } }); toolbar1.add(flipVert); flipHorz.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fliphorz.png"))); // NOI18N flipHorz.setToolTipText("Fill Horizontal"); flipHorz.setFocusable(false); flipHorz.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); flipHorz.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); flipHorz.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { flipHorzActionPerformed(evt); } }); toolbar1.add(flipHorz); scaleSize.setIcon(new javax.swing.ImageIcon(getClass().getResource("/scale.png"))); // NOI18N scaleSize.setToolTipText("Scale Image"); scaleSize.setFocusable(false); scaleSize.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); scaleSize.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); scaleSize.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { scaleSizeActionPerformed(evt); } }); toolbar1.add(scaleSize); jLabel4.setText(":"); toolbar1.add(jLabel4); fillMode.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fillmode.png"))); // NOI18N fillMode.setToolTipText("Fill Mode"); fillMode.setFocusable(false); fillMode.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); fillMode.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); toolbar1.add(fillMode); fillAlpha.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fillAlpha.png"))); // NOI18N fillAlpha.setToolTipText("Fill setting Transparent Level (Alpha)"); fillAlpha.setFocusable(false); fillAlpha.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); fillAlpha.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); fillAlpha.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { fillAlphaActionPerformed(evt); } }); toolbar1.add(fillAlpha); fillEdge.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fillEdge.png"))); // NOI18N fillEdge.setToolTipText("Fill edges only"); fillEdge.setFocusable(false); fillEdge.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); fillEdge.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); toolbar1.add(fillEdge); round.setIcon(new javax.swing.ImageIcon(getClass().getResource("/round.png"))); // NOI18N round.setToolTipText("Rounded Box"); round.setFocusable(false); round.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); round.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); round.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { roundActionPerformed(evt); } }); toolbar1.add(round); selkeyclr.setIcon(new javax.swing.ImageIcon(getClass().getResource("/keyclr.png"))); // NOI18N selkeyclr.setToolTipText("Place selection box except for background color pixels."); selkeyclr.setFocusable(false); selkeyclr.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); selkeyclr.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); toolbar1.add(selkeyclr); jLabel5.setText(":"); toolbar1.add(jLabel5); selectFont.setIcon(new javax.swing.ImageIcon(getClass().getResource("/font.png"))); // NOI18N selectFont.setToolTipText("Select Font"); selectFont.setFocusable(false); selectFont.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); selectFont.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); selectFont.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { selectFontActionPerformed(evt); } }); toolbar1.add(selectFont); changeSize.setIcon(new javax.swing.ImageIcon(getClass().getResource("/size.png"))); // NOI18N changeSize.setToolTipText("Change Image Size"); changeSize.setFocusable(false); changeSize.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); changeSize.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); changeSize.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { changeSizeActionPerformed(evt); } }); toolbar1.add(changeSize); backswap.setIcon(new javax.swing.ImageIcon(getClass().getResource("/backswap.png"))); // NOI18N backswap.setToolTipText("Alternate background checker pattern."); backswap.setFocusable(false); backswap.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); backswap.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); backswap.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { backswapActionPerformed(evt); } }); toolbar1.add(backswap); toolbar2.setFloatable(false); toolbar2.setRollover(true); foreColor.setText("ForeColor"); foreColor.setToolTipText("Fore Color"); foreColor.setFocusable(false); foreColor.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); foreColor.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); foreColor.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { foreColorActionPerformed(evt); } }); toolbar2.add(foreColor); swap.setIcon(new javax.swing.ImageIcon(getClass().getResource("/swap.png"))); // NOI18N swap.setToolTipText("Swap Colors"); swap.setFocusable(false); swap.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); swap.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); swap.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { swapActionPerformed(evt); } }); toolbar2.add(swap); backColor.setText("BackColor"); backColor.setToolTipText("Back Color"); backColor.setFocusable(false); backColor.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); backColor.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); backColor.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { backColorActionPerformed(evt); } }); toolbar2.add(backColor); width.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1px", "2px", "3px", "4px" })); width.setToolTipText("Line Width"); width.setMaximumSize(new java.awt.Dimension(50, 28)); toolbar2.add(width); paintMode.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Normal", "Transparent", "Gradient (cyclic)", "Gradient (acyclic)", "Gradient (radial - no cycle)", "Gradient (radial - reflect)", "Gradient (radial - repeat)", "Gaussian Blur", "Pixelate", "Chrome" })); paintMode.setToolTipText("Paint Mode"); paintMode.setMaximumSize(new java.awt.Dimension(180, 28)); paintMode.setMinimumSize(new java.awt.Dimension(1, 1)); paintMode.setName(""); // NOI18N paintMode.setPreferredSize(new java.awt.Dimension(180, 20)); paintMode.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { paintModeActionPerformed(evt); } }); toolbar2.add(paintMode); colorLayer.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "ARGB", "A---", "-R--", "--G-", "---B" })); colorLayer.setToolTipText("Color Layer"); colorLayer.setLightWeightPopupEnabled(false); colorLayer.setMaximumSize(new java.awt.Dimension(70, 28)); colorLayer.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { colorLayerActionPerformed(evt); } }); toolbar2.add(colorLayer); layersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/layers.png"))); // NOI18N layersButton.setToolTipText("Show Image Layers Window"); layersButton.setFocusable(false); layersButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); layersButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); layersButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { layersButtonActionPerformed(evt); } }); toolbar2.add(layersButton); toolbar3.setFloatable(false); toolbar3.setRollover(true); jLabel1.setText("Threshold:"); jLabel1.setToolTipText("0=match exact : 100=match all"); toolbar3.add(jLabel1); threshold.setText("0%"); threshold.setToolTipText("0=match exact : 100=match all"); threshold.setMaximumSize(new java.awt.Dimension(30, 14)); threshold.setMinimumSize(new java.awt.Dimension(25, 14)); threshold.setPreferredSize(new java.awt.Dimension(25, 14)); toolbar3.add(threshold); thresholdSlider.setMaximum(255); thresholdSlider.setToolTipText("0=match exact : 100=match all"); thresholdSlider.setValue(0); thresholdSlider.setEnabled(false); thresholdSlider.setMaximumSize(new java.awt.Dimension(120, 23)); thresholdSlider.setMinimumSize(new java.awt.Dimension(100, 23)); thresholdSlider.setPreferredSize(new java.awt.Dimension(100, 23)); thresholdSlider.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { thresholdSliderStateChanged(evt); } }); toolbar3.add(thresholdSlider); jLabel2.setText("Transparent:"); jLabel2.setToolTipText("0=opaque : 100=transparent"); toolbar3.add(jLabel2); alpha.setText("0%"); alpha.setToolTipText("0=transparent : 100=opaque"); alpha.setMaximumSize(new java.awt.Dimension(30, 14)); alpha.setMinimumSize(new java.awt.Dimension(25, 14)); alpha.setPreferredSize(new java.awt.Dimension(25, 14)); toolbar3.add(alpha); alphaSlider.setMaximum(255); alphaSlider.setToolTipText("0=transparent : 100=opaque"); alphaSlider.setValue(0); alphaSlider.setEnabled(false); alphaSlider.setMaximumSize(new java.awt.Dimension(120, 23)); alphaSlider.setMinimumSize(new java.awt.Dimension(100, 23)); alphaSlider.setPreferredSize(new java.awt.Dimension(100, 23)); alphaSlider.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { alphaSliderStateChanged(evt); } }); toolbar3.add(alphaSlider); jLabel6.setText("Zoom:"); toolbar3.add(jLabel6); zoom.setMaximum(5); zoom.setPaintLabels(true); zoom.setValue(2); zoom.setMaximumSize(new java.awt.Dimension(120, 23)); zoom.setMinimumSize(new java.awt.Dimension(100, 23)); zoom.setPreferredSize(new java.awt.Dimension(100, 23)); zoom.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { zoomStateChanged(evt); } }); toolbar3.add(zoom); zoomText.setText("100%"); toolbar3.add(zoomText); tabs.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT); tabs.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { tabsStateChanged(evt); } }); status.setText("status"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(toolbar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(toolbar1, javax.swing.GroupLayout.DEFAULT_SIZE, 639, Short.MAX_VALUE) .addComponent(status) .addComponent(tabs) .addComponent(toolbar3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(toolbar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(toolbar2, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(toolbar3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tabs, javax.swing.GroupLayout.PREFERRED_SIZE, 423, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(status, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); }// </editor-fold>//GEN-END:initComponents private void tabsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabsStateChanged if (curIdx != -1) { unselectTool(curIdx); updateStatus(); } int idx = getidx(); curIdx = idx; if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; int scale = (int)pc.scale; switch (scale) { case 25: zoom.setValue(0); break; case 50: zoom.setValue(1); break; case 100: zoom.setValue(2); break; case 200: zoom.setValue(3); break; case 400: zoom.setValue(4); break; case 800: zoom.setValue(5); break; } colorLayer.setSelectedIndex(pc.getColorLayer()); if (layers != null) { layers.setup(pc); } }//GEN-LAST:event_tabsStateChanged private void selBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selBoxActionPerformed if (selectedTool == tools.selBox) return; unselectTool(getidx()); selectTool(tools.selBox); }//GEN-LAST:event_selBoxActionPerformed private void fillActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fillActionPerformed if (selectedTool == tools.fill) return; unselectTool(getidx()); selectTool(tools.fill); }//GEN-LAST:event_fillActionPerformed private void pickColorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pickColorActionPerformed if (selectedTool == tools.pickColor) return; unselectTool(getidx()); selectTool(tools.pickColor); }//GEN-LAST:event_pickColorActionPerformed private void pencilActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pencilActionPerformed if (selectedTool == tools.pencil) return; unselectTool(getidx()); selectTool(tools.pencil); }//GEN-LAST:event_pencilActionPerformed private void textActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_textActionPerformed if (selectedTool == tools.text) return; unselectTool(getidx()); selectTool(tools.text); }//GEN-LAST:event_textActionPerformed private void curveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_curveActionPerformed if (selectedTool == tools.curve) return; unselectTool(getidx()); selectTool(tools.curve); }//GEN-LAST:event_curveActionPerformed private void lineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_lineActionPerformed if (selectedTool == tools.line) return; unselectTool(getidx()); selectTool(tools.line); }//GEN-LAST:event_lineActionPerformed private void boxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_boxActionPerformed if (selectedTool == tools.box) return; unselectTool(getidx()); selectTool(tools.box); }//GEN-LAST:event_boxActionPerformed private void circleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_circleActionPerformed if (selectedTool == tools.circle) return; unselectTool(getidx()); selectTool(tools.circle); }//GEN-LAST:event_circleActionPerformed private void foreColorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_foreColorActionPerformed foreClr = selectClr(foreClr, "Select foreground colour"); updateClr(foreColor, foreClr); }//GEN-LAST:event_foreColorActionPerformed private void backColorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backColorActionPerformed backClr = selectClr(backClr, "Select background colour"); updateClr(backColor, backClr); }//GEN-LAST:event_backColorActionPerformed private void subActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_subActionPerformed if (selectedTool == tools.sub) return; unselectTool(getidx()); selectTool(tools.sub); }//GEN-LAST:event_subActionPerformed private void swapActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_swapActionPerformed swapColors(); }//GEN-LAST:event_swapActionPerformed private void rotateCWActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rotateCWActionPerformed PaintCanvas pc = imageTabs.get(getidx()).pc; pc.rotateCW(); pc.resizeBorder(); pc.parentPanel.revalidate(); pc.repaint(); }//GEN-LAST:event_rotateCWActionPerformed private void rotateCCWActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rotateCCWActionPerformed PaintCanvas pc = imageTabs.get(getidx()).pc; pc.rotateCCW(); pc.resizeBorder(); pc.parentPanel.revalidate(); pc.repaint(); }//GEN-LAST:event_rotateCCWActionPerformed private void flipVertActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_flipVertActionPerformed PaintCanvas pc = imageTabs.get(getidx()).pc; pc.flipVert(); pc.repaint(); }//GEN-LAST:event_flipVertActionPerformed private void flipHorzActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_flipHorzActionPerformed PaintCanvas pc = imageTabs.get(getidx()).pc; pc.flipHorz(); pc.repaint(); }//GEN-LAST:event_flipHorzActionPerformed private void scaleSizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_scaleSizeActionPerformed GetXY dialog = new GetXY(frame, true, "Scale Image (percentage)", 100, 100); dialog.setVisible(true); if (dialog.w <= 0) return; PaintCanvas pc = imageTabs.get(getidx()).pc; int orgLayer = pc.getColorLayer(); if (orgLayer != 0) { pc.changeColorLayer(0); } pc.scaleImage(dialog.w, dialog.h); pc.resizeBorder(); if (orgLayer != 0) { pc.changeColorLayer(orgLayer); } pc.parentPanel.revalidate(); pc.repaint(); }//GEN-LAST:event_scaleSizeActionPerformed private void selectFontActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectFontActionPerformed JFontChooser fc = new JFontChooser(null); fc.showDialog(textFont); Font newFont = fc.getFont(); if (newFont == null) return; textFont = newFont; }//GEN-LAST:event_selectFontActionPerformed private void changeSizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changeSizeActionPerformed PaintCanvas pc = imageTabs.get(getidx()).pc; int ox = pc.getUnscaledWidth(); int oy = pc.getUnscaledHeight(); GetXY dialog = new GetXY(frame, true, "Set Image Size (pixels)", ox, oy); dialog.setVisible(true); if ((dialog.w <= 0) || (dialog.h <= 0)) return; changeSize(pc, dialog.w - ox, dialog.h - oy, false); }//GEN-LAST:event_changeSizeActionPerformed private void roundActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_roundActionPerformed if (round.isSelected()) { GetXY getarcs = new GetXY(null, true, "Get Arc X/Y", arcX, arcY); getarcs.setVisible(true); if (getarcs.w == -1) { round.setSelected(false); return; } arcX = getarcs.w; arcY = getarcs.h; } }//GEN-LAST:event_roundActionPerformed private void colorLayerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_colorLayerActionPerformed layerChanged(); }//GEN-LAST:event_colorLayerActionPerformed private void paintModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_paintModeActionPerformed paintModeChanged(); }//GEN-LAST:event_paintModeActionPerformed private void backswapActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backswapActionPerformed int idx = getidx(); if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; if (pc == null) return; pc.swap = !pc.swap; pc.backClear(); pc.repaint(); }//GEN-LAST:event_backswapActionPerformed private void layersButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_layersButtonActionPerformed if (layers != null) { layers.dispose(); } else { int idx = getidx(); if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; if (pc == null) return; layers = new LayersWindow(this); layers.setup(pc); layers.setVisible(true); Point pt = layersButton.getLocationOnScreen(); pt.y += layersButton.getHeight(); layers.setLocation(pt); } }//GEN-LAST:event_layersButtonActionPerformed private void thresholdSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_thresholdSliderStateChanged threshold.setText("" + getThresholdPercent() + "%"); }//GEN-LAST:event_thresholdSliderStateChanged private void alphaSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_alphaSliderStateChanged alpha.setText("" + getAlphaPercent() + "%"); }//GEN-LAST:event_alphaSliderStateChanged private void zoomStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_zoomStateChanged changeScale(); }//GEN-LAST:event_zoomStateChanged private void fillAlphaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fillAlphaActionPerformed if (selectedTool == tools.fill) { alphaSlider.setEnabled(fillAlpha.isSelected()); } }//GEN-LAST:event_fillAlphaActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel alpha; private javax.swing.JSlider alphaSlider; private javax.swing.JButton backColor; private javax.swing.JButton backswap; private javax.swing.JToggleButton box; private javax.swing.JButton changeSize; private javax.swing.JToggleButton circle; private javax.swing.JComboBox colorLayer; private javax.swing.JToggleButton curve; private javax.swing.JToggleButton fill; private javax.swing.JToggleButton fillAlpha; private javax.swing.JToggleButton fillEdge; private javax.swing.JToggleButton fillMode; private javax.swing.JButton flipHorz; private javax.swing.JButton flipVert; private javax.swing.JButton foreColor; private javax.swing.ButtonGroup group; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JLabel jLabel6; private javax.swing.JButton layersButton; private javax.swing.JToggleButton line; private javax.swing.JComboBox paintMode; private javax.swing.JToggleButton pencil; private javax.swing.JToggleButton pickColor; private javax.swing.JButton rotateCCW; private javax.swing.JButton rotateCW; private javax.swing.JToggleButton round; private javax.swing.JButton scaleSize; private javax.swing.JToggleButton selBox; private javax.swing.JButton selectFont; private javax.swing.JToggleButton selkeyclr; private javax.swing.JTextField status; private javax.swing.JToggleButton sub; private javax.swing.JButton swap; private javax.swing.JTabbedPane tabs; private javax.swing.JToggleButton text; private javax.swing.JLabel threshold; private javax.swing.JSlider thresholdSlider; private javax.swing.JToolBar toolbar1; private javax.swing.JToolBar toolbar2; private javax.swing.JToolBar toolbar3; private javax.swing.JComboBox width; private javax.swing.JSlider zoom; private javax.swing.JLabel zoomText; // End of variables declaration//GEN-END:variables //global data private JFrame frame; public boolean active = true; public enum tools { selBox, fill, pickColor, pencil, text, curve, line, box, circle, sub }; /* public enum modes { Normal, Transparent, Gradient_cyclic, Gradient_acyclic, Gradient_radial_no_cycle ,Gradient_radial_reflect, Gradient_radial_repeat };*/ public tools selectedTool = tools.selBox; public int foreClr = 0x000000; public int backClr = 0xffffff; public int selClr = 0x000000; public int init_x = 256, init_y = 256; public boolean haveSel; public int selX1, selY1, selX2, selY2; public int clipBoard[], cbX, cbY; public int cx[] = new int[4], cy[] = new int[4]; //curve points public int cpt = -1; //current curve point (0-3) public int gx[] = new int[2], gy[] = new int[2]; //grad points public int gfx, gfy; //grad focus point (radial) public boolean getGradPoints = false; public boolean getGradFocus = false; public String textText = ""; public Font textFont = new Font("Default", Font.PLAIN, 12); public int curIdx = -1; public int arcX = 25, arcY = 25; public Config config; public LayersWindow layers; public JFImage rotateImg; public JFImage pixel; private String configFolder = JF.getUserPath(); private String configFile = "/.jfpaint.xml"; private String currentPath; private int filter_radius; private int filter_pixelSize; //pixelation private float filter_amount, filter_exposure; private float rotate; private int scretchDir; public static class Config { public String code; } private void loadConfig() { defaultConfig(); try { XML xml = new XML(); FileInputStream fis = new FileInputStream(configFolder + configFile); xml.read(fis); xml.writeClass(config); } catch (FileNotFoundException e1) { defaultConfig(); } catch (Exception e2) { JFLog.log(e2); defaultConfig(); } } private void defaultConfig() { config = new Config(); } private void saveConfig() { try { XML xml = new XML(); FileOutputStream fos = new FileOutputStream(configFolder + configFile); xml.readClass("jfpaint", config); xml.write(fos); fos.close(); } catch (Exception e) { JFLog.log(e); } } private class PanelLayout implements LayoutManager { // private Vector<Component> list = new Vector<Component>(); public void addLayoutComponent(String string, Component cmp) { // list.add(cmp); } public void removeLayoutComponent(Component cmp) { // list.remove(cmp); } public Dimension preferredLayoutSize(Container c) { return new Dimension(1, 1); } public Dimension minimumLayoutSize(Container c) { return new Dimension(1, 1); } public void layoutContainer(Container c) { //assumes images are added Center,East,South try { Dimension d1, d2, d3, ds; int cnt = c.getComponentCount(); int x = c.getWidth(); int y = c.getHeight(); d1 = toolbar1.getPreferredSize(); toolbar1.setBounds(0, 0, x, d1.height); d2 = toolbar2.getPreferredSize(); toolbar2.setBounds(0, d1.height, x, d2.height); d3 = toolbar3.getPreferredSize(); toolbar3.setBounds(0, d1.height + d2.height, x, d3.height); ds = status.getPreferredSize(); tabs.setBounds(0, d1.height + d2.height + d3.height, x, y - (d1.height + d2.height + d3.height + ds.height)); status.setBounds(0, y - ds.height, x, ds.height); } catch (Exception e) { e.printStackTrace(); } } } private class ImageLayout implements LayoutManager { // private Vector<Component> list = new Vector<Component>(); public void addLayoutComponent(String string, Component cmp) { // list.add(cmp); } public void removeLayoutComponent(Component cmp) { // list.remove(cmp); } public Dimension preferredLayoutSize(Container c) { int cnt = c.getComponentCount(); if (cnt != 4) return new Dimension(1, 1); PaintCanvas pc = (PaintCanvas)c.getComponent(0); return new Dimension(pc.getScaledWidth() + 10, pc.getScaledHeight() + 10); } public Dimension minimumLayoutSize(Container c) { return preferredLayoutSize(c); } public void layoutContainer(Container c) { //assumes images are added Center,East,South,Corner int cnt = c.getComponentCount(); if (cnt != 4) return; PaintCanvas pc = (PaintCanvas)c.getComponent(0); int x = pc.getScaledWidth(); int y = pc.getScaledHeight(); //System.out.println("layout:" + x + "," + y); pc.setBounds(0, 0, x, y); Component img1 = c.getComponent(1); img1.setBounds(x, 0, 10, y); Component img2 = c.getComponent(2); img2.setBounds(0, y, x, 10); Component img3 = c.getComponent(3); img3.setBounds(x, y, 10, 10); } } private class ImageTab { PaintCanvas pc; JPanel panel; JScrollPane scroll; File filename; }; private Vector<ImageTab> imageTabs = new Vector<ImageTab>(); public void openTab() { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.addChoosableFileFilter(new FileNameExtensionFilter("JFPAINT", "jfpaint")); chooser.addChoosableFileFilter(new FileNameExtensionFilter("JPEG", "jpg", "jpeg")); chooser.addChoosableFileFilter(new FileNameExtensionFilter("PNG", "png")); chooser.addChoosableFileFilter(new FileNameExtensionFilter("BMP", "bmp")); chooser.addChoosableFileFilter(new FileNameExtensionFilter("XPM", "xpm")); chooser.setMultiSelectionEnabled(false); chooser.setCurrentDirectory(new File(currentPath)); if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return; loadTab(chooser.getSelectedFile().toString()); } private void loadTab(String filename) { if (filename.length() == 0) return; int idx = getidx(); ImageTab tab = imageTabs.get(idx); boolean emptyFile; //check if current page is "untitled" and !dirty if (tab.filename.toString().equals("untitled") && imageTabs.get(idx).pc.dirty == false) { //load on current page tab.filename = new File(filename); emptyFile = tab.filename.length() == 0; } else { addTab("newfile"); idx = tabs.getTabCount() - 1; tab = imageTabs.get(idx); tab.filename = new File(filename); emptyFile = tab.filename.length() == 0; } currentPath = tab.filename.getAbsoluteFile().getParent(); if (currentPath == null) currentPath = JF.getUserPath() + "/Pictures"; String name = tab.filename.toString(); int fidx = name.lastIndexOf("/"); if (fidx != -1) name = name.substring(fidx+1); tabs.setTitleAt(idx, name); PaintCanvas pc = tab.pc; if (!emptyFile && !loadImage(pc, filename)) { closeTab(false); if (tabs.getTabCount() == 0) addTab("untitled"); JF.showError("Error", "Failed to load file"); return; } pc.grabFocus(); pc.resizeBorder(); pc.parentPanel.revalidate(); updateStatus(); } public void loadFiles(String files[]) { if (files == null) return; for(int a=0;a<files.length;a++) { loadTab(files[a]); } } private ImageTab addTab(String title) { ImageTab tab = new ImageTab(); tab.panel = new JPanel(new ImageLayout()); tab.scroll = new JScrollPane(tab.panel); tab.pc = new PaintCanvas(tab.panel, tab.scroll); tab.pc.setImageSize(init_x, init_y); tab.pc.img[0].fill(0,0,init_x,init_y,backClr); tab.pc.createBorders(); tab.panel.add(tab.pc, "CENTER"); tab.panel.add(tab.pc.border_east, "EAST"); tab.panel.add(tab.pc.border_south, "SOUTH"); tab.panel.add(tab.pc.border_corner, "CORNER"); tab.pc.resizeBorder(); tab.filename = new File(title); tab.pc.dirty = false; imageTabs.add(tab); tabs.addTab(title, tab.scroll); tabs.setSelectedComponent(tab.scroll); tab.pc.requestFocus(); if (layers != null) { layers.setup(tab.pc); } return tab; } private int getidx() { return tabs.getSelectedIndex(); } private boolean loadImage(PaintCanvas pc, String filename) { pc.disableScale = true; JFImage img = new JFImage(); String format = getFormat(filename); if (format == null) return false; boolean result, multi = false; if (format.equals("jfpaint")) { multi = true; try { JFPaint imgs; FileInputStream fis = new FileInputStream(filename); ObjectInputStream ois = new ObjectInputStream(fis); imgs = (JFPaint)ois.readObject(); ois.close(); fis.close(); int w = 0,h = 0; for(int a=0;a<imgs.images.length;a++) { img = new JFImage(); ByteArrayInputStream bais = new ByteArrayInputStream(imgs.images[a].png); if (!img.loadPNG(bais)) throw new Exception("jfpaint sub-png load failed"); if (a == 0) { w = img.getWidth(); h = img.getHeight(); pc.setImageSize(w, h); } else { pc.addImageLayer(); } pc.setImageLayer(a); int px[] = img.getPixels(); pc.img[a].putPixels(px, 0, 0, w, h, 0); pc.name[a] = imgs.images[a].name; } pc.setImageLayer(0); result = true; } catch (Exception e) { JF.showError("Error", e.toString()); result = false; } } else if (format.equals("bmp")) result = img.loadBMP(filename); else if (format.equals("svg")) result = img.loadSVG(filename); else if (format.equals("jpg")) result = img.loadJPG(filename); else if (format.equals("xpm")) result = img.loadXPM(filename); else result = img.load(filename); if (result && !multi) { int w = img.getWidth(); int h = img.getHeight(); pc.setImageSize(w, h); int px[] = img.getPixels(); pc.img[pc.getImageLayer()].putPixels(px, 0, 0, w, h, 0); } pc.disableScale = false; return result; } private void updateStatus() { int idx = getidx(); if (idx == -1) {status.setText("?"); return;} if (getGradPoints) { status.setText("Draw a line to define Gradient start and end points."); return; } if (getGradFocus) { status.setText("Click a point to define Gradient focal point."); return; } ImageTab tab = imageTabs.get(idx); String str = "size:" + tab.pc.getUnscaledWidth() + "x" + tab.pc.getUnscaledHeight(); str += " mouse: " + tab.pc.mx + "," + tab.pc.my; if (tab.pc.button == MouseEvent.BUTTON1) str += " box: " + Math.abs(tab.pc.mx - tab.pc.sx + 1) + "x" + Math.abs(tab.pc.my - tab.pc.sy + 1); status.setText(str); } private int selectClr(int oldClr, String name) { Color newClr = JColorChooser.showDialog(this, name, new Color(oldClr)); if (newClr == null) return oldClr; return newClr.getRGB() & JFImage.RGB_MASK; } private void updateClr(JButton button, int clr) { JFImage blk = new JFImage(16,16); blk.fill(0,0,16,16,clr); button.setIcon(blk); button.setText(""); } public void newTab() { GetXY dialog = new GetXY(frame, true, "New Image (pixels)", init_x, init_y); dialog.setVisible(true); if (dialog.w == -1) return; int idx = getidx(); ImageTab tab = imageTabs.get(idx); if (!(tab.filename.toString().equals("untitled") && imageTabs.get(idx).pc.dirty == false)) { addTab("untitled"); idx = tabs.getTabCount() - 1; tab = imageTabs.get(idx); } tab.pc.setImageSize(dialog.w, dialog.h); tab.pc.img[tab.pc.getImageLayer()].fill(0,0,dialog.w,dialog.h,backClr); repaint(); } public boolean closeTab(boolean exiting) { int idx = getidx(); if (tabs.getTabCount() == 0) return true; if (imageTabs.get(idx).pc.dirty) { switch (JF.showConfirm3("Save?", "Save first?")) { case JF.YES: if (!saveTab()) return false; case JF.CANCEL: return false; case JF.NO: break; } } curIdx = -1; imageTabs.remove(idx); tabs.remove(idx); if (exiting) return true; if (tabs.getTabCount() == 0) addTab("untitled"); return true; } public boolean saveTab() { int idx = getidx(); if (imageTabs.get(idx).filename.toString().equals("untitled")) { return saveAs(); } PaintCanvas pc = imageTabs.get(idx).pc; String filename = imageTabs.get(idx).filename.toString(); String format = getFormat(filename); if (format == null) return false; boolean saved = false; pc.disableScale = true; pc.clearUndo(); pc.applyColorLayer(); if (format.equals("jfpaint")) { int cnt = pc.getImageLayers(); JFPaint imgs = new JFPaint(); imgs.images = new JFPaintImage[cnt]; try { for(int a=0;a<cnt;a++) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (!pc.img[a].savePNG(baos)) throw new Exception("jfpaint sub-png save failed"); imgs.images[a] = new JFPaintImage(); imgs.images[a].png = baos.toByteArray(); imgs.images[a].name = pc.name[a]; } FileOutputStream fos = new FileOutputStream(filename); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(imgs); oos.close(); fos.close(); return true; } catch (Exception e) { JF.showError("Error", e.toString()); return false; } } else { if (pc.getImageLayers() > 1) { if (!JF.showConfirm("Combine Layers?", "Saving in this format will combine all layers, are you sure?")) return false; } JFImage img = pc.combineImageLayers(); if (format.equals("bmp")) saved = img.saveBMP(filename); else if (format.equals("svg")) saved = img.saveSVG(filename); else if (format.equals("jpg")) saved = img.saveJPG(filename); else saved = img.save(filename, format); } pc.disableScale = false; if (saved) pc.dirty = false; return saved; } public boolean saveAs() { int idx = getidx(); JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.addChoosableFileFilter(new FileNameExtensionFilter("JFPAINT", "jfpaint")); chooser.addChoosableFileFilter(new FileNameExtensionFilter("JPEG", "jpg", "jpeg")); chooser.addChoosableFileFilter(new FileNameExtensionFilter("PNG", "png")); chooser.addChoosableFileFilter(new FileNameExtensionFilter("BMP", "bmp")); chooser.addChoosableFileFilter(new FileNameExtensionFilter("SVG", "svg")); chooser.setMultiSelectionEnabled(false); chooser.setCurrentDirectory(new File(currentPath)); if (chooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) { ImageTab tab = imageTabs.get(idx); tab.pc.setDirty(); tab.filename = chooser.getSelectedFile(); String format = getFormat(tab.filename.toString()); if (format == null) { String ext = chooser.getFileFilter().getDescription().toLowerCase(); if (ext.equals("all files")) { if (tab.pc.getImageLayers() == 1) ext = "png"; //default if one image layer else ext = "jfpaint"; //default if > 1 image layer } if (ext.equals("jpeg")) ext = "jpg"; tab.filename = new File(tab.filename.toString() + "." + ext); } currentPath = tab.filename.getAbsoluteFile().getParent(); if (currentPath == null) currentPath = JF.getUserPath() + "/Pictures"; String name = tab.filename.toString(); int fidx = name.lastIndexOf("/"); if (fidx != -1) name = name.substring(fidx+1); tabs.setTitleAt(idx, name); return saveTab(); } return false; } private void selectAll() { int idx = getidx(); unselectTool(idx); selBox.setSelected(true); selectTool(tools.selBox); PaintCanvas pc = imageTabs.get(idx).pc; selX1 = selY1 = 0; selX2 = pc.img[pc.getImageLayer()].getWidth()-1; selY2 = pc.img[pc.getImageLayer()].getHeight()-1; haveSel = true; cutSel(); pasteSel(selX1, selY1, false); pc.drag = true; } private String getFormat(String filename) { int idx = filename.lastIndexOf("."); if (idx == -1) return null; String format = filename.substring(idx+1).toLowerCase(); if (format.equals("jfpaint")) return "jfpaint"; if (format.equals("png")) return "png"; if (format.equals("bmp")) return "bmp"; if (format.equals("jpg")) return "jpg"; if (format.equals("jpeg")) return "jpg"; if (format.equals("svg")) return "svg"; if (format.equals("xpm")) return "xpm"; System.out.println("Unsupported format:" + format); return null; } private void selectTool(tools tool) { selectedTool = tool; switch (tool) { case fill: thresholdSlider.setEnabled(true); alphaSlider.setEnabled(fillAlpha.isSelected() || paintMode.getSelectedIndex() == 1); break; case sub: thresholdSlider.setEnabled(true); alphaSlider.setEnabled(paintMode.getSelectedIndex() == 1); break; default: thresholdSlider.setEnabled(false); alphaSlider.setEnabled(paintMode.getSelectedIndex() == 1); break; } } private void unselectTool(int idx) { if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; pc.disableScale = true; switch (selectedTool) { case selBox: if (pc.drag) { drawSel(pc); clearSel(pc); pc.drag = false; } pc.foreClear(); break; case text: if (pc.drag) { drawText(pc); clearSel(pc); pc.drag = false; } pc.foreClear(); break; case curve: cpt = -1; break; } pc.disableScale = false; } private void print() { //TODO } public void delSel() { if (selectedTool != tools.selBox) return; if (!haveSel) return; int tmp; if (selX1 > selX2) {tmp=selX1; selX1=selX2; selX2=tmp;} if (selY1 > selY2) {tmp=selY1; selY1=selY2; selY2=tmp;} int idx = getidx(); int w = selX2-selX1+1; int h = selY2-selY1+1; PaintCanvas pc = imageTabs.get(idx).pc; pc.img[pc.getImageLayer()].fill(selX1,selY1,w,h,backClr); clearSel(pc); pc.drag = false; } public void cutSel() { if (selectedTool != tools.selBox) return; if (!haveSel) return; int tmp; if (selX1 > selX2) {tmp=selX1; selX1=selX2; selX2=tmp;} if (selY1 > selY2) {tmp=selY1; selY1=selY2; selY2=tmp;} int idx = getidx(); cbX = selX2-selX1+1; cbY = selY2-selY1+1; PaintCanvas pc = imageTabs.get(idx).pc; pc.disableScale = true; JFImage clip = new JFImage(cbX,cbY); clipBoard = pc.img[pc.getImageLayer()].getPixels(selX1,selY1,cbX,cbY); clip.putPixels(clipBoard,0,0,cbX,cbY,0); JFClipboard.writeImage(clip.getImage()); int layer = pc.getImageLayer(); if (layer == 0) { pc.img[layer].fill(selX1,selY1,cbX,cbY,backClr); } else { pc.img[layer].fill(selX1,selY1,cbX,cbY,backClr,true); //alpha = transparent } pc.disableScale = false; } public void copySel() { if (selectedTool != tools.selBox) return; if (!haveSel) return; int tmp; if (selX1 > selX2) {tmp=selX1; selX1=selX2; selX2=tmp;} if (selY1 > selY2) {tmp=selY1; selY1=selY2; selY2=tmp;} int idx = getidx(); cbX = selX2-selX1+1; cbY = selY2-selY1+1; PaintCanvas pc = imageTabs.get(idx).pc; JFImage clip = new JFImage(cbX,cbY); clipBoard = pc.img[pc.getImageLayer()].getPixels(selX1,selY1,cbX,cbY); clip.putPixels(clipBoard,0,0,cbX,cbY,0); JFClipboard.writeImage(clip.getImage()); } public void pasteSel(int x, int y, boolean sysClipBoard) { if (colorLayer.getSelectedIndex() != 0) return; rotate = 0f; if (clipBoard == null || sysClipBoard) { java.awt.Image img = JFClipboard.readImage(); if (img == null) return; JFImage image = JFClipboard.convertImage(img); cbX = image.getWidth(); cbY = image.getHeight(); clipBoard = image.getPixels(); } int idx = getidx(); PaintCanvas pc = imageTabs.get(idx).pc; if (selectedTool != tools.selBox) { unselectTool(idx); selBox.setSelected(true); selectTool(tools.selBox); } pc.disableScale = true; minSize(pc, x + cbX, y + cbY); selX1 = x; selY1 = y; selX2 = x+cbX; selY2 = y+cbY; haveSel = true; foreDrawSel(pc); pc.drag = true; pc.disableScale = false; } private void clearSel(PaintCanvas pc) { pc.foreClear(); haveSel = false; } private void drawSel(PaintCanvas pc) { if (cbX == 0 || cbY == 0) return; //shouldn't happen ??? int px[]; if (selkeyclr.isSelected()) { int cnt = cbX * cbY; px = new int[cnt]; System.arraycopy(clipBoard, 0, px, 0, cnt); for(int a=0;a<cnt;a++) { if ((px[a] & JFImage.RGB_MASK) == backClr) { px[a] = 0; } } } else { px = clipBoard; } pc.putPixels(px, selX1, selY1, selX2 - selX1, selY2 - selY1, cbX, cbY, rotate); pc.img[pc.getImageLayer()].repaint(); } private void foreDrawSel(PaintCanvas pc) { int px[]; if (selkeyclr.isSelected()) { int cnt = cbX * cbY; px = new int[cnt]; System.arraycopy(clipBoard, 0, px, 0, cnt); for(int a=0;a<cnt;a++) { if ((px[a] & JFImage.RGB_MASK) == backClr) { px[a] = 0; } } } else { px = clipBoard; } pc.forePutPixels(px, selX1, selY1, selX2 - selX1, selY2 - selY1, cbX, cbY, rotate); pc.foreDrawSelBox(selX1,selY1,selX2,selY2,rotate); } private void drawText(PaintCanvas pc) { assignPaint(pc.cimg, true); pc.setFont(textFont); int x=selX1; int y=selY1; Rectangle2D rect = textFont.getMaxCharBounds(pc.img[pc.getImageLayer()].getGraphics2D().getFontRenderContext()); int fy = (int)rect.getHeight(); pc.drawText(textText.split("\n"), x, y, fy, 1, 1, rotate); textText = ""; } private void foreDrawText(PaintCanvas pc) { FontRenderContext frc = pc.img[pc.getImageLayer()].getGraphics2D().getFontRenderContext(); Rectangle2D rect = textFont.getMaxCharBounds(pc.img[pc.getImageLayer()].getGraphics2D().getFontRenderContext()); int fx = (int)rect.getWidth(); int fy = (int)rect.getHeight(); int mx = 1; int my; int lx = 0; assignPaint(pc.fimg, true); pc.foreClear(); pc.foreDrawSelBox(selX1, selY1, selX2, selY2, rotate); pc.foreSetFont(textFont); String text; if (pc.textCursor) { pc.textCursor = false; text = textText + "\u2588"; } else { pc.textCursor = true; text = textText; } String lns[] = text.split("\n", -1); my = lns.length * fy; int x=selX1; int y=selY1; for(int a=0;a<lns.length;a++) { lx = (int)textFont.getStringBounds(lns[a], frc).getWidth() + 6; if (lx > mx) mx = lx; } pc.foreDrawText(lns, x, y, fy, 1, 1, rotate); if ((selX2 - selX1) < mx) selX2 = selX1 + mx; if ((selY2 - selY1) < my) selY2 = selY1 + my; } private void repaintTool(PaintCanvas pc) { if (!pc.drag) return; assignPaint(pc.fimg, pc.button == MouseEvent.BUTTON1); pc.disableScale = true; pc.foreClear(); switch (selectedTool) { case selBox: foreDrawSel(pc); break; case text: foreDrawText(pc); break; } pc.repaint(); pc.disableScale = false; } private void undo() { unselectTool(getidx()); PaintCanvas pc = imageTabs.get(getidx()).pc; pc.disableScale = true; pc.undo(); pc.disableScale = false; } private void redo() { unselectTool(getidx()); PaintCanvas pc = imageTabs.get(getidx()).pc; pc.disableScale = true; pc.redo(); pc.disableScale = false; } private void repaintImage() { int idx = getidx(); imageTabs.get(idx).pc.repaint(); } private void minSize(PaintCanvas pc, int w, int h) { //scaling on pc is already disabled int pw = pc.getUnscaledWidth(); int ph = pc.getUnscaledHeight(); int dx = 0; int dy = 0; if (w > pw) dx = w - pw; if (h > ph) dy = h - ph; if (dx == 0 && dy == 0) return; changeSize(pc, dx, dy, false); } private void changeSize(PaintCanvas pc, int dx, int dy, boolean scaled) { float orgScale = pc.scale; int orgLayer = pc.getColorLayer(); int x = pc.getUnscaledWidth(); int y = pc.getUnscaledHeight(); if (x + dx < 1) { dx = -x + 1; } if (y + dy < 1) { dy = -y + 1; } if (scaled) { dx /= (pc.scale / 100f); dy /= (pc.scale / 100f); } if (orgLayer != 0) { pc.changeColorLayer(0); } if (orgScale != 100) pc.setScale(100); int cnt = pc.getImageLayers(); int px[][] = new int[cnt][]; for (int a=0;a<cnt;a++) { px[a] = pc.img[a].getPixels(); } pc.setImageSize(x + dx,y + dy); for(int a=0;a<cnt;a++) { pc.img[a].putPixels(px[a], 0,0, x,y, 0); if (dx > 0) { if (a == 0) pc.img[a].fill(x,0,dx,y + dy,backClr); else pc.img[a].fill(x,0,dx,y + dy,backClr, true); } if (dy > 0) { if (a == 0) pc.img[a].fill(0,y,x + dx,dy,backClr); else pc.img[a].fill(0,y,x + dx,dy,backClr, true); } if ((dx > 0) && (dy > 0)) { if (a == 0) pc.img[a].fill(x,y,dx,dy,backClr); else pc.img[a].fill(x,y,dx,dy,backClr, true); } } if (orgScale != 100) pc.setScale(orgScale); if (orgLayer != 0) { pc.changeColorLayer(orgLayer); } pc.resizeBorder(); repaintTool(pc); updateStatus(); } private void paintModeChanged() { getGradPoints = false; getGradFocus = false; updateStatus(); int mode = paintMode.getSelectedIndex(); if (mode == 0) { fillAlpha.setEnabled(true); fillEdge.setEnabled(true); } else { fillAlpha.setEnabled(false); fillAlpha.setSelected(false); fillEdge.setEnabled(false); fillEdge.setSelected(false); } alphaSlider.setEnabled(false); GetValue dialog; GetValue2 dialog2; switch (mode) { case 0: //normal break; case 1: //transparent alphaSlider.setEnabled(true); break; case 2: case 3: case 4: case 5: case 6: getGradPoints = true; updateStatus(); break; case 7: dialog = new GetValue(null, true, "Enter Gaussian Blur parameters", "radius", 2, 64, 5); dialog.setVisible(true); filter_radius = dialog.value; if (filter_radius == -1) filter_radius = 2; break; case 8: dialog = new GetValue(null, true, "Enter Pixelate parameters", "pixel size", 2, 64, 5); dialog.setVisible(true); filter_pixelSize = dialog.value; if (filter_pixelSize == -1) filter_pixelSize = 2; break; case 9: dialog2 = new GetValue2(null, true, "Enter Chrome parameters" , "amount", 0, 100, 50 , "exposure", 0, 100, 100 ); dialog2.setVisible(true); filter_amount = dialog2.value1; if (filter_amount == -1) filter_pixelSize = 50; filter_amount /= 100f; filter_exposure = dialog2.value2; if (filter_exposure == -1) filter_exposure = 100; filter_exposure /= 100f; break; } if (mode >= 7 ) { switch (selectedTool) { case box: break; default: unselectTool(getidx()); box.doClick(); break; } pencil.setEnabled(false); fill.setEnabled(false); fillMode.setEnabled(false); text.setEnabled(false); curve.setEnabled(false); line.setEnabled(false); circle.setEnabled(false); round.setEnabled(false); selectFont.setEnabled(false); sub.setEnabled(false); thresholdSlider.setEnabled(false); rotateCW.setEnabled(false); rotateCCW.setEnabled(false); flipVert.setEnabled(false); flipHorz.setEnabled(false); selkeyclr.setEnabled(false); fillMode.setSelected(false); } else { pencil.setEnabled(true); fill.setEnabled(true); fillMode.setEnabled(true); text.setEnabled(true); curve.setEnabled(true); line.setEnabled(true); circle.setEnabled(true); round.setEnabled(true); selectFont.setEnabled(true); sub.setEnabled(true); thresholdSlider.setEnabled(true); rotateCW.setEnabled(true); rotateCCW.setEnabled(true); flipVert.setEnabled(true); flipHorz.setEnabled(true); selkeyclr.setEnabled(true); } } private int getAlphaLevel() { int al = alphaSlider.getValue(); return 255 - al; } private int getAlphaPercent() { int al = alphaSlider.getValue(); return al * 100 / 255; } private int getThresholdLevel() { int al = thresholdSlider.getValue(); if (al < 0) al = 0; if (al > 255) al = 255; return al; } private int getThresholdPercent() { int al = thresholdSlider.getValue(); if (al < 0) al = 0; if (al > 255) al = 255; return al * 100 / 255; } private float gradRadius() { float rise = Math.abs(gy[0] - gy[1]); float run = Math.abs(gx[0] - gx[1]); return (float)Math.sqrt(rise*rise + run*run); } private void assignPaint(JFImage img, boolean button1) { Paint paint = null; int clr; switch (paintMode.getSelectedIndex()) { case 0: //normal if (button1) clr = foreClr; else clr = backClr; switch (colorLayer.getSelectedIndex()) { case 0: //ARGB paint = new Color(clr); break; case 1: //A //find avg of color components and assign to rgb int r = (clr & 0xff0000) >> 16; int g = (clr & 0x00ff00) >> 8; int b = (clr & 0x0000ff); clr = (r + g + b) / 3; paint = new Color((clr << 16) | (clr << 8) | (clr)); break; case 2: //R paint = new Color(clr & 0xff0000); break; case 3: //G paint = new Color(clr & 0x00ff00); break; case 4: //B paint = new Color(clr & 0x0000ff); break; } break; case 1: //transparent if (button1) clr = foreClr; else clr = backClr; paint = new Color(clr | (getAlphaLevel() << 24), true); break; case 2: //grad (cyclic) paint = new GradientPaint(gx[0], gy[0], new Color(foreClr), gx[1], gy[1], new Color(backClr), true); break; case 3: //grad (acyclic) paint = new GradientPaint(gx[0], gy[0], new Color(foreClr), gx[1], gy[1], new Color(backClr), false); break; case 4: //grad (radial - no cycle) paint = new RadialGradientPaint(gx[0], gy[0], gradRadius(), gfx, gfy, new float[] {0.0f, 1.0f}, new Color[] {new Color(foreClr), new Color(backClr)}, MultipleGradientPaint.CycleMethod.NO_CYCLE); break; case 5: //grad (radial - reflect) paint = new RadialGradientPaint(gx[0], gy[0], gradRadius(), gfx, gfy, new float[] {0.0f, 1.0f}, new Color[] {new Color(foreClr), new Color(backClr)}, MultipleGradientPaint.CycleMethod.REFLECT); break; case 6: //grad (radial - repeat) paint = new RadialGradientPaint(gx[0], gy[0], gradRadius(), gfx, gfy, new float[] {0.0f, 1.0f}, new Color[] {new Color(foreClr), new Color(backClr)}, MultipleGradientPaint.CycleMethod.REPEAT); break; } img.getGraphics2D().setPaint(paint); } public void swapColors() { int tmp = foreClr; foreClr = backClr; backClr = tmp; updateClr(foreColor, foreClr); updateClr(backColor, backClr); } public void changeScale() { PaintCanvas pc = imageTabs.get(getidx()).pc; int newScale = -1; switch (zoom.getValue()) { case 0: newScale = 25; break; case 1: newScale = 50; break; case 2: newScale = 100; break; case 3: newScale = 200; break; case 4: newScale = 400; break; case 5: newScale = 800; break; } zoomText.setText(Integer.toString(newScale) + "%"); pc.setScale(newScale); pc.parentPanel.revalidate(); pc.resizeBorder(); pc.repaint(); } public void actionPerformed(ActionEvent e) { //Swing Timer repaintTool(imageTabs.get(getidx()).pc); } public void doPaste(boolean sysClipBoard) { int idx = getidx(); if (idx == -1) return; unselectTool(idx); selBox.setSelected(true); selectTool(tools.selBox); Point pt = imageTabs.get(idx).scroll.getViewport().getViewPosition(); //scale point float scale = imageTabs.get(idx).pc.scale / 100f; pt.x = (int)(pt.x / scale); pt.y = (int)(pt.y / scale); pasteSel(pt.x, pt.y, sysClipBoard); } public boolean dispatchKeyEvent(KeyEvent evt) { int id = evt.getID(); switch (id) { case KeyEvent.KEY_TYPED: keyTyped(evt); break; case KeyEvent.KEY_PRESSED: keyPressed(evt); break; case KeyEvent.KEY_RELEASED: keyReleased(evt); break; } return false; //pass on as normal } public static final int NONE = 0; public static final int N = 1; public static final int E = 2; public static final int S = 3; public static final int W = 4; public static final int NE = 5; public static final int NW = 6; public static final int SE = 7; public static final int SW = 8; public static final int R = 9; public static final int INSIDE = 10; public static final int OUTSIDE = 11; public float rad2deg(float rad) { return rad * 180f / (float)Math.PI; } /** Get selection box point. * Adjusts for rotation. */ public int getSelBoxPt(int x,int y) { if (!haveSel) return OUTSIDE; if (rotate != 0f) { GLMatrix mat = new GLMatrix(); mat.addRotate(rad2deg(rotate), 0, 0, 1); GLVector3 vec = new GLVector3(); vec.v[0] = x - selX1; vec.v[1] = y - selY1; vec.v[2] = 0; //z mat.mult(vec); x = (int)vec.v[0] + selX1; y = (int)vec.v[1] + selY1; } int ox = x - selX1; int oy = y - selY1; int width = selX2 - selX1 + 1; int height = selY2 - selY1 + 1; if (x >= selX1 && x <= selX2 && y >= selY1 && y <= selY2) { return INSIDE; } else { if (ox >= width+5 && ox <= width+15 && oy >= height+5 && oy <= height+15) return R; if (ox < -5 || ox > width+5) return OUTSIDE; if (oy < -5 || oy > height+5) return OUTSIDE; int x1 = 0; int y1 = 0; int x2 = width; int y2 = height; if (ox >= x2 && oy >= y2) return SE; if (ox <= x1 && oy >= y2) return SW; if (ox >= x2 && oy <= y1) return NE; if (ox <= x1 && oy <= y1) return NW; if (oy <= y1) return N; if (oy >= y2) return S; if (ox <= x1) return W; if (ox >= x2) return E; return INSIDE; //should not happen } } public void keyPressed(KeyEvent evt) { //Key Pressed int f1 = evt.getKeyCode(); int f2 = evt.getModifiers(); int idx = getidx(); if ((f1 == KeyEvent.VK_F1) && (f2 == 0)) { JOptionPane.showMessageDialog(this, "jfpaint/" + version + "\n\n" + "F1 = Help\n" + "CTRL-O = Open\n" + "CTRL-W = Close\n" + "CTRL-S = Save\n" + "CTRL-Q = Save As\n" + "CTRL-P = Print\n" + "CTRL-X = Cut\n" + "CTRL-C = Copy\n" + "CTRL-V = Paste\n" + "CTRL-Z = Undo\n" + "CTRL-Y = Redo\n" + "ALT-# = Switch to document\n\n" , "Help", JOptionPane.INFORMATION_MESSAGE); return; } if ((f1 == KeyEvent.VK_ESCAPE) && (f2 == 0)) { unselectTool(getidx()); return; } if ((f1 == KeyEvent.VK_N) && (f2 == KeyEvent.CTRL_MASK)) { addTab("untitled"); return; } if ((f1 == KeyEvent.VK_S) && (f2 == KeyEvent.CTRL_MASK)) { saveTab(); return; } if ((f1 == KeyEvent.VK_Q) && (f2 == KeyEvent.CTRL_MASK)) { saveAs(); return; } if ((f1 == KeyEvent.VK_W) && (f2 == KeyEvent.CTRL_MASK)) { closeTab(false); return; } if ((f1 == KeyEvent.VK_O) && (f2 == KeyEvent.CTRL_MASK)) { openTab(); return; } if ((f1 == KeyEvent.VK_P) && (f2 == KeyEvent.CTRL_MASK)) { print(); return; } if ((f1 == KeyEvent.VK_A) && (f2 == KeyEvent.CTRL_MASK)) { selectAll(); return; } if ((f1 == KeyEvent.VK_DELETE) && (f2 == 0)) { delSel(); return; } if ((f1 == KeyEvent.VK_Z) && (f2 == KeyEvent.CTRL_MASK)) { undo(); return; } if ((f1 == KeyEvent.VK_Y) && (f2 == KeyEvent.CTRL_MASK)) { redo(); return; } if ((f2 == KeyEvent.ALT_MASK) && (f1 >= KeyEvent.VK_0) && (f1 <= KeyEvent.VK_9)) { idx = f1 - KeyEvent.VK_0; if (idx == 0) idx = 9; else idx--; if (idx >= imageTabs.size()) return; unselectTool(getidx()); tabs.setSelectedIndex(idx); return; } if ((f2 == KeyEvent.ALT_MASK) && (f1 == KeyEvent.VK_MINUS)) {unselectTool(getidx()); tabs.setSelectedIndex(10);} if ((f2 == KeyEvent.ALT_MASK) && (f1 == KeyEvent.VK_EQUALS)) {unselectTool(getidx()); tabs.setSelectedIndex(11);} } public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) {} //the following mouse events are from PaintCanvas, not this Panel public void mouseClicked(MouseEvent e) { JComponent c = (JComponent)e.getComponent(); if (c instanceof Border) return; PaintCanvas pc = (PaintCanvas)c; int x = (int)(e.getX() / (pc.scale / 100f)); int y = (int)(e.getY() / (pc.scale / 100f)); if (getGradFocus) { gfx = x; gfy = y; getGradFocus = false; updateStatus(); return; } pc.disableScale = true; pc.setLineWidth(width.getSelectedIndex()+1); assignPaint(pc.cimg, e.getButton() == MouseEvent.BUTTON1); switch (selectedTool) { default: pc.disableScale = false; return; case pencil: pc.drawLine(x, y, x, y); break; } pc.disableScale = false; pc.setDirty(); pc.repaint(); } public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) { JComponent c = (JComponent)e.getComponent(); PaintCanvas pc; boolean border = false; if (c instanceof Border) { Border b = (Border)c; pc = b.pc; border = true; } else { pc = (PaintCanvas)c; } pc.grabFocus(); pc.button = e.getButton(); int x = (int)(e.getX() / (pc.scale / 100f)); int y = (int)(e.getY() / (pc.scale / 100f)); if (border) { //start to drag size pc.sx = x; pc.sy = y; pc.createUndo(); return; } if (getGradPoints) { gx[0] = x; gy[0] = y; return; } if (getGradFocus) return; pc.disableScale = true; pc.setLineWidth(width.getSelectedIndex()+1); assignPaint(pc.cimg, e.getButton() == MouseEvent.BUTTON1); switch (selectedTool) { default: pc.disableScale = false; return; case pencil: pc.createUndo(); pc.sx = x; pc.sy = y; pc.disableScale = false; return; case selBox: case text: int pt = getSelBoxPt(x,y); switch (pt) { default: scretchDir = pt; pc.sx = x; pc.sy = y; break; case INSIDE: scretchDir = NONE; pc.drag = true; pc.sx = x; pc.sy = y; break; case OUTSIDE: scretchDir = NONE; if (pc.drag) { if (selectedTool == tools.selBox) drawSel(pc); else drawText(pc); pc.drag = false; clearSel(pc); } rotate = 0f; selX1 = x; selY1 = y; haveSel = true; if (selectedTool == tools.text) textText = ""; break; } //no break case line: case box: case circle: case sub: pc.createUndo(); pc.sx = x; pc.sy = y; pc.disableScale = false; return; case curve: if (cpt == -1) { pc.createUndo(); cpt++; cx[cpt] = x; cy[cpt] = y; cpt++; } else { mouseDragged(e); } pc.disableScale = false; return; case fill: int clr = foreClr; if (e.getButton() == MouseEvent.BUTTON3) clr = backClr; switch (colorLayer.getSelectedIndex()) { case 0: //ARGB break; case 1: //A //find avg of color components and assign to rgb int r = (clr & 0xff0000) >> 16; int g = (clr & 0x00ff00) >> 8; int b = (clr & 0x0000ff); clr = (r + g + b) / 3; clr = (clr << 16) | (clr << 8) | (clr); break; case 2: //R clr &= 0xff0000; break; case 3: //G clr &= 0x00ff00; break; case 4: //B clr &= 0x0000ff; break; } pc.createUndo(); switch (paintMode.getSelectedIndex()) { case 0: if (fillAlpha.isSelected()) pc.fillFast(x, y, clr | getAlphaLevel() << 24, true, fillEdge.isSelected(), getThresholdLevel()); else pc.fillFast(x, y, clr, false, fillEdge.isSelected(), getThresholdLevel()); break; default: pc.fillSlow(x, y, fillEdge.isSelected(), getThresholdLevel()); break; } break; case pickColor: if (e.getButton() == MouseEvent.BUTTON1) { foreClr = pc.img[pc.getImageLayer()].getPixel(x, y); updateClr(foreColor, foreClr); } if (e.getButton() == MouseEvent.BUTTON3) { backClr = pc.img[pc.getImageLayer()].getPixel(x, y); updateClr(backColor, backClr); } pc.disableScale = false; return; } pc.disableScale = false; pc.setDirty(); pc.repaint(); } public void mouseReleased(MouseEvent e) { JComponent c = (JComponent)e.getComponent(); if (c instanceof Border) return; PaintCanvas pc = (PaintCanvas)c; pc.button = -1; int tmp; int x = (int)(e.getX() / (pc.scale / 100f)); int y = (int)(e.getY() / (pc.scale / 100f)); if (getGradPoints) { gx[1] = x; gy[1] = y; pc.foreClear(); getGradPoints = false; if (paintMode.getSelectedIndex() > 3) getGradFocus = true; updateStatus(); pc.repaint(); return; } if (getGradFocus) return; pc.disableScale = true; pc.setLineWidth(width.getSelectedIndex()+1); assignPaint(pc.cimg, e.getButton() == MouseEvent.BUTTON1); switch (selectedTool) { default: pc.disableScale = false; return; case line: pc.drawLine(pc.sx, pc.sy, x, y); pc.foreClear(); break; case box: switch (paintMode.getSelectedIndex()) { default: if (fillMode.isSelected()) { if (round.isSelected()) pc.fillRoundBox(pc.sx, pc.sy, x, y, arcX, arcY); else pc.fillBox(pc.sx, pc.sy, x, y); } else { if (round.isSelected()) pc.drawRoundBox(pc.sx, pc.sy, x, y, arcX, arcY); else pc.drawBox(pc.sx, pc.sy, x, y); } break; case 7: pc.blur(pc.sx, pc.sy, x, y, filter_radius); break; case 8: pc.pixelate(pc.sx, pc.sy, x, y, filter_pixelSize); break; case 9: pc.chrome(pc.sx, pc.sy, x, y, filter_amount, filter_exposure); break; } pc.foreClear(); break; case circle: if (fillMode.isSelected()) { pc.fillCircle(pc.sx, pc.sy, x, y); } else { pc.drawCircle(pc.sx, pc.sy, x, y); } pc.foreClear(); break; case selBox: if (pc.drag) { pc.disableScale = false; return; } selX2 = x; selY2 = y; if ((selX1 == selX2) && (selY1 == selY2)) {haveSel = false; pc.foreClear(); pc.repaint(); return;} if (selX1 > selX2) {tmp=selX1; selX1=selX2; selX2=tmp;} if (selY1 > selY2) {tmp=selY1; selY1=selY2; selY2=tmp;} //copySel(); cutSel(); pasteSel(selX1, selY1, false); pc.drag = true; scretchDir = NONE; break; case curve: cx[cpt] = x; cy[cpt] = y; cpt++; if (cpt != 4) return; //draw final curve pc.drawCurve(cx, cy); cpt = -1; break; case pencil: break; case sub: switch (paintMode.getSelectedIndex()) { case 0: pc.subBoxFast(pc.sx, pc.sy, x, y, backClr, foreClr, getThresholdLevel()); break; default: pc.subBoxSlow(pc.sx, pc.sy, x, y, backClr, getThresholdLevel()); break; } pc.foreClear(); break; case text: if (pc.drag) return; selX2 = x; selY2 = y; if ((selX1 == selX2) && (selY1 == selY2)) {haveSel = false; pc.foreClear(); pc.repaint(); return;} if (selX1 > selX2) {tmp=selX1; selX1=selX2; selX2=tmp;} if (selY1 > selY2) {tmp=selY1; selY1=selY2; selY2=tmp;} pc.drag = true; break; } pc.disableScale = false; pc.setDirty(); pc.repaint(); } public void mouseDragged(MouseEvent e) { JComponent c = (JComponent)e.getComponent(); if (c instanceof Border) { Border b = (Border)c; int x = (int)(e.getX() / (b.pc.scale / 100f)); int y = (int)(e.getY() / (b.pc.scale / 100f)); //changing size if (b.borderType == Border.Types.east) { changeSize(b.pc, x - b.pc.sx, 0, true); } if (b.borderType == Border.Types.south) { changeSize(b.pc, 0, y - b.pc.sy, true); } if (b.borderType == Border.Types.corner) { changeSize(b.pc, x - b.pc.sx, y - b.pc.sy, true); } imageTabs.get(getidx()).scroll.doLayout(); doLayout(); return; } PaintCanvas pc = (PaintCanvas)c; int x = (int)(e.getX() / (pc.scale / 100f)); int y = (int)(e.getY() / (pc.scale / 100f)); if (scretchDir != NONE) { float width = selX2 - selX1; float height = selY2 - selY1; switch(scretchDir) { case NW: selX1 = x; selY1 = y; break; case N: selY1 = y; break; case NE: selY1 = y; selX2 = x; break; case E: selX2 = x; break; case SE: selX2 = x; selY2 = y; break; case S: selY2 = y; break; case SW: selX1 = x; selY2 = y; break; case W: selX1 = x; break; case R: rotate = (y - selY2) / height; break; } return; } pc.disableScale = true; if (getGradPoints) { pc.foreClear(); pc.fimg.getGraphics2D().setPaint(new Color(foreClr)); pc.foreDrawLine(gx[0], gy[0], x, y); pc.repaint(); pc.disableScale = false; return; } if (getGradFocus) { pc.disableScale = false; return; //shouldn't happen unless user can't read } assignPaint(pc.cimg, pc.button == MouseEvent.BUTTON1); assignPaint(pc.fimg, pc.button == MouseEvent.BUTTON1); switch (selectedTool) { case pencil: pc.drawLine(pc.sx, pc.sy, x, y); pc.sx = x; pc.sy = y; break; case line: pc.foreClear(); pc.foreDrawLine(pc.sx, pc.sy, x, y); break; case box: pc.foreClear(); if (fillMode.isSelected()) { if (round.isSelected()) pc.foreFillRoundBox(pc.sx, pc.sy, x, y, arcX, arcY); else pc.foreFillBox(pc.sx, pc.sy, x, y); } else { if (round.isSelected()) pc.foreDrawRoundBox(pc.sx, pc.sy, x, y, arcX, arcY); else pc.foreDrawBox(pc.sx, pc.sy, x, y); } break; case circle: pc.foreClear(); if (fillMode.isSelected()) { pc.foreFillCircle(pc.sx, pc.sy, x, y); } else { pc.foreDrawCircle(pc.sx, pc.sy, x, y); } break; case selBox: if (!haveSel) break; if (pc.drag) { pc.foreClear(); int dx = (x - pc.sx); int dy = (y - pc.sy); selX1 += dx; selY1 += dy; selX2 += dx; selY2 += dy; foreDrawSel(pc); pc.sx = x; pc.sy = y; } else { selX2 = x; selY2 = y; pc.foreClear(); pc.foreDrawSelBox(selX1, selY1, selX2, selY2, rotate); } break; case curve: cx[cpt] = x; cy[cpt] = y; pc.foreClear(); switch (cpt) { case 1: pc.foreDrawLine(cx[0], cy[0], cx[1], cy[1]); break; case 2: cx[3] = cx[1]; cy[3] = cy[1]; //no break case 3: pc.foreDrawCurve(cx, cy); break; } break; case sub: pc.foreClear(); pc.foreDrawBox(pc.sx, pc.sy, x, y); break; case text: if (!haveSel) break; if (pc.drag) { pc.foreClear(); int dx = (x - pc.sx); int dy = (y - pc.sy); selX1 += dx; selY1 += dy; selX2 += dx; selY2 += dy; pc.sx = x; pc.sy = y; } else { selX2 = x; selY2 = y; } foreDrawText(pc); break; } pc.disableScale = false; updateStatus(); pc.setDirty(); pc.repaint(); } public void mouseMoved(MouseEvent e) { updateStatus(); } public void keyTypedOnImage(char key) { if (selectedTool != tools.text) return; PaintCanvas pc = imageTabs.get(getidx()).pc; if (key == 8) { if (textText.length() > 0) textText = textText.substring(0,textText.length()-1); } else if (key == 10) { textText += "\n"; } else { textText += key; } foreDrawText(pc); pc.repaint(); } public int getLayer() { return colorLayer.getSelectedIndex(); } public void layerChanged() { int idx = getidx(); unselectTool(idx); switch (selectedTool) { case selBox: case sub: pencil.doClick(); } PaintCanvas pc = imageTabs.get(idx).pc; pc.changeColorLayer(colorLayer.getSelectedIndex()); if (colorLayer.getSelectedIndex() > 0) { paintMode.setSelectedIndex(0); paintMode.setEnabled(false); selBox.setEnabled(false); sub.setEnabled(false); thresholdSlider.setEnabled(false); rotateCW.setEnabled(false); rotateCCW.setEnabled(false); flipVert.setEnabled(false); flipHorz.setEnabled(false); selkeyclr.setEnabled(false); fillAlpha.setSelected(false); fillAlpha.setEnabled(false); fillEdge.setSelected(false); fillEdge.setEnabled(false); } else { int mode = paintMode.getSelectedIndex(); paintMode.setEnabled(true); selBox.setEnabled(true); sub.setEnabled(true); thresholdSlider.setEnabled(true); rotateCW.setEnabled(true); rotateCCW.setEnabled(true); flipVert.setEnabled(true); flipHorz.setEnabled(true); selkeyclr.setEnabled(true); fillAlpha.setEnabled(mode == 0); fillEdge.setEnabled(mode == 0); } repaint(); pc.repaint(); } public boolean closeAll() { while (tabs.getTabCount() > 0) { if (!closeTab(true)) return false; } return true; } public void addLayer() { int idx = getidx(); if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; if (pc == null) return; pc.addImageLayer(); pc.repaint(); } public void delLayer() { int idx = getidx(); if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; if (pc == null) return; pc.removeImageLayer(pc.getImageLayer()); pc.repaint(); } public void editLayer() { int idx = getidx(); if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; if (pc == null) return; int layer = pc.getImageLayer(); String newName = JF.getString("Edit layer name", pc.name[layer]); if (newName == null) return; pc.name[layer] = newName; } public void dupLayer() { int idx = getidx(); if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; if (pc == null) return; int layer = pc.getImageLayer(); int px[] = pc.img[layer].getPixels(); pc.addImageLayer(); pc.swapLayers(layer+1, pc.getImageLayers()-1); pc.img[layer+1].putPixels(px, 0, 0, pc.getUnscaledWidth(), pc.getUnscaledHeight(), 0); pc.repaint(); } public void mergeLayer() { int idx = getidx(); if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; if (pc == null) return; int layer = pc.getImageLayer(); if (layer == 0) return; pc.img[layer-1].getGraphics().drawImage(pc.img[layer].getImage(), 0, 0, null); pc.removeImageLayer(layer); pc.setImageLayer(layer-1); pc.repaint(); } public void moveLayerUp() { int idx = getidx(); if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; if (pc == null) return; int layer = pc.getImageLayer(); if (layer == 0) return; pc.swapLayers(layer, layer-1); pc.setImageLayer(layer-1); pc.repaint(); } public void moveLayerDown() { int idx = getidx(); if (idx == -1) return; PaintCanvas pc = imageTabs.get(idx).pc; if (pc == null) return; int layer = pc.getImageLayer(); if (layer == pc.getImageLayers()-1) return; pc.swapLayers(layer, layer+1); pc.setImageLayer(layer+1); pc.repaint(); } }