1 | /* |
2 | * Copyright (c) 2005 The PseudoQ Project. |
3 | * |
4 | * This file is part of PseudoQ. |
5 | * |
6 | * PseudoQ is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU Lesser General Public License as published by |
8 | * the Free Software Foundation; either version 2.1 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * PseudoQ is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public License |
17 | * along with PseudoQ; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ |
20 | |
21 | package net.sourceforge.pseudoq.gui; |
22 | |
23 | import java.awt.Dimension; |
24 | import java.awt.Graphics2D; |
25 | import javax.swing.RepaintManager; |
26 | |
27 | import net.sourceforge.pseudoq.model.Coordinate; |
28 | |
29 | /** |
30 | * Custom swing component for displaying and editing a puzzle. |
31 | * @author <a href="http://sourceforge.net/users/stevensa">Andrew Stevens</a> |
32 | */ |
33 | public class PuzzlePanel extends javax.swing.JComponent implements java.awt.print.Printable { |
34 | /** Log4J logger */ |
35 | private static final org.apache.log4j.Logger log = |
36 | org.apache.log4j.LogManager.getLogger(PuzzlePanel.class); |
37 | |
38 | /** Creates new form PuzzlePanel */ |
39 | public PuzzlePanel() { |
40 | initComponents(); |
41 | } |
42 | |
43 | /** This method is called from within the constructor to |
44 | * initialize the form. |
45 | * WARNING: Do NOT modify this code. The content of this method is |
46 | * always regenerated by the Form Editor. |
47 | */ |
48 | // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents |
49 | private void initComponents() { |
50 | |
51 | setLayout(new java.awt.BorderLayout()); |
52 | |
53 | addMouseListener(new java.awt.event.MouseAdapter() { |
54 | public void mousePressed(java.awt.event.MouseEvent evt) { |
55 | formMousePressed(evt); |
56 | } |
57 | }); |
58 | |
59 | } |
60 | // </editor-fold>//GEN-END:initComponents |
61 | |
62 | private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed |
63 | // figure out what cell was clicked on |
64 | int x = (evt.getX() - 5) / painter.getSize(); |
65 | int y = (evt.getY() - 5) / painter.getSize(); |
66 | if (x >= 0 && x < puzzle.getSize() && y >= 0 && y < puzzle.getSize()) { |
67 | Coordinate newCell = new Coordinate(y, x); |
68 | if ((currentCell == null || !currentCell.equals(newCell)) && puzzle.getGrid().get(newCell) != null) { |
69 | setCurrentCell(newCell); |
70 | repaint(); |
71 | } |
72 | } |
73 | }//GEN-LAST:event_formMousePressed |
74 | |
75 | // Variables declaration - do not modify//GEN-BEGIN:variables |
76 | // End of variables declaration//GEN-END:variables |
77 | |
78 | /** |
79 | * Holds painter to be used to draw the grid. |
80 | */ |
81 | private GridPainter painter = null; |
82 | /** |
83 | * Holds value of property puzzle. |
84 | */ |
85 | private net.sourceforge.pseudoq.model.Puzzle puzzle; |
86 | /** |
87 | * Holds value of property showSolution. |
88 | */ |
89 | private boolean showSolution; |
90 | /** |
91 | * Holds value of property currentCell. |
92 | */ |
93 | private Coordinate currentCell; |
94 | |
95 | /** |
96 | * Getter for property puzzle. |
97 | * @return Value of property puzzle. |
98 | */ |
99 | public net.sourceforge.pseudoq.model.Puzzle getPuzzle() { |
100 | return this.puzzle; |
101 | } |
102 | |
103 | /** |
104 | * Setter for property puzzle. |
105 | * @param puzzle New value of property puzzle. |
106 | */ |
107 | public void setPuzzle(net.sourceforge.pseudoq.model.Puzzle puzzle) { |
108 | this.puzzle = puzzle; |
109 | painter = GridPainterFactory.newInstance(puzzle.getType()); |
110 | } |
111 | |
112 | /** |
113 | * Getter for property showSolution. |
114 | * @return Value of property showSolution. |
115 | */ |
116 | public boolean isShowSolution() { |
117 | return this.showSolution; |
118 | } |
119 | |
120 | /** |
121 | * Setter for property showSolution. |
122 | * @param showSolution New value of property showSolution. |
123 | */ |
124 | public void setShowSolution(boolean showSolution) { |
125 | this.showSolution = showSolution; |
126 | repaint(); |
127 | } |
128 | |
129 | public void paintComponent(java.awt.Graphics g) { |
130 | super.paintComponent(g); |
131 | if (painter != null) { |
132 | painter.drawGrid(g); |
133 | if (showSolution && puzzle.isSolved()) { |
134 | painter.printValues(g, puzzle.getSolution().getGrid(), puzzle.getGivens()); |
135 | } else { |
136 | painter.printValues(g, puzzle.getGrid(), puzzle.getGivens()); |
137 | } |
138 | if (currentCell != null) { |
139 | painter.highlightCell(g, currentCell); |
140 | } |
141 | } |
142 | } |
143 | |
144 | public Dimension getPreferredSize() { |
145 | Dimension retval = null; |
146 | |
147 | if (painter != null) { |
148 | retval = painter.getPreferredSize(); |
149 | } else { |
150 | retval = new Dimension(100, 100); |
151 | } |
152 | |
153 | return retval; |
154 | } |
155 | |
156 | /** |
157 | * Utility field used by event firing mechanism. |
158 | */ |
159 | private javax.swing.event.EventListenerList listenerList = null; |
160 | |
161 | /** |
162 | * Utility field used by bound properties. |
163 | */ |
164 | private java.beans.PropertyChangeSupport propertyChangeSupport = |
165 | new java.beans.PropertyChangeSupport(this); |
166 | |
167 | /** |
168 | * Adds a PropertyChangeListener to the listener list. |
169 | * @param l The listener to add. |
170 | */ |
171 | public void addPropertyChangeListener(java.beans.PropertyChangeListener l) { |
172 | propertyChangeSupport.addPropertyChangeListener(l); |
173 | } |
174 | |
175 | /** |
176 | * Removes a PropertyChangeListener from the listener list. |
177 | * @param l The listener to remove. |
178 | */ |
179 | public void removePropertyChangeListener(java.beans.PropertyChangeListener l) { |
180 | propertyChangeSupport.removePropertyChangeListener(l); |
181 | } |
182 | |
183 | /** |
184 | * Getter for property currentCell. |
185 | * @return Value of property currentCell. |
186 | */ |
187 | public Coordinate getCurrentCell() { |
188 | return this.currentCell; |
189 | } |
190 | |
191 | /** |
192 | * Setter for property currentCell. |
193 | * @param currentCell New value of property currentCell. |
194 | */ |
195 | public void setCurrentCell(Coordinate currentCell) { |
196 | Coordinate oldCurrentCell = this.currentCell; |
197 | this.currentCell = currentCell; |
198 | propertyChangeSupport.firePropertyChange("currentCell", oldCurrentCell, currentCell); |
199 | } |
200 | |
201 | public int print(java.awt.Graphics g, java.awt.print.PageFormat pageFormat, int pageIndex) |
202 | throws java.awt.print.PrinterException { |
203 | int retval = 0; |
204 | |
205 | if (pageIndex > 0) { |
206 | retval = NO_SUCH_PAGE; |
207 | } else { |
208 | Graphics2D g2d = (Graphics2D) g; |
209 | |
210 | // don't print cursor |
211 | Coordinate oldCurrentCell = this.currentCell; |
212 | this.currentCell = null; |
213 | // move to the printable area |
214 | g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); |
215 | // check if the puzzle is bigger than the page, and scale to fit |
216 | Dimension size = painter.getPreferredSize(); |
217 | if (pageFormat.getImageableWidth() < size.getWidth() || |
218 | pageFormat.getImageableHeight() < size.getHeight()) { |
219 | double scalingFactor = Math.min(pageFormat.getImageableWidth() / size.getWidth(), |
220 | pageFormat.getImageableHeight() / size.getHeight()); |
221 | g2d.scale(scalingFactor, scalingFactor); |
222 | } |
223 | // disable double buffering while printing, as it's unnecessary |
224 | RepaintManager manager = RepaintManager.currentManager(this); |
225 | manager.setDoubleBufferingEnabled(false); |
226 | // print grid |
227 | this.paint(g2d); |
228 | // restore previous state |
229 | manager.setDoubleBufferingEnabled(true); |
230 | this.currentCell = oldCurrentCell; |
231 | |
232 | retval = PAGE_EXISTS; |
233 | } |
234 | |
235 | return retval; |
236 | } |
237 | |
238 | /** |
239 | * Get the painter that will be used to draw the grid. |
240 | * @return The painter. |
241 | */ |
242 | GridPainter getPainter() { |
243 | return this.painter; |
244 | } |
245 | |
246 | } |