change how to layout windows (testing)
@@ -25,13 +25,11 @@ | ||
25 | 25 | import java.awt.BorderLayout; |
26 | 26 | import java.awt.Color; |
27 | 27 | import java.awt.Component; |
28 | -import java.awt.Container; | |
29 | 28 | import java.awt.FlowLayout; |
30 | 29 | import java.awt.GradientPaint; |
31 | 30 | import java.awt.Graphics; |
32 | 31 | import java.awt.Graphics2D; |
33 | 32 | import java.awt.Paint; |
34 | -import java.awt.Point; | |
35 | 33 | import java.awt.event.ActionEvent; |
36 | 34 | import java.awt.event.ActionListener; |
37 | 35 | import java.awt.event.ComponentAdapter; |
@@ -45,8 +43,6 @@ | ||
45 | 43 | import javax.swing.JPanel; |
46 | 44 | import javax.swing.JPopupMenu; |
47 | 45 | import javax.swing.JScrollPane; |
48 | -import javax.swing.JSplitPane; | |
49 | -import javax.swing.JViewport; | |
50 | 46 | import javax.swing.SwingUtilities; |
51 | 47 | import javax.swing.border.EmptyBorder; |
52 | 48 | import javax.swing.event.ChangeEvent; |
@@ -141,12 +137,15 @@ | ||
141 | 137 | int l = s.getInsets().left; |
142 | 138 | int r = s.getInsets().right; |
143 | 139 | int sw = s.getVerticalScrollBar().getWidth(); |
144 | - int rw = NineUtilities.getRootPanel(win).getWidth(); | |
145 | - int wd = rw - l - r - sw; | |
146 | - if (scrollpane.getRowHeader() != null) { | |
147 | - wd -= scrollpane.getRowHeader().getWidth(); | |
140 | + RootPanel rootPanel = NineUtilities.getRootPanel(win); | |
141 | + if (rootPanel != null) { | |
142 | + int rw = NineUtilities.getRootPanel(win).getWidth(); | |
143 | + int wd = rw - l - r - sw; | |
144 | + if (scrollpane.getRowHeader() != null) { | |
145 | + wd -= scrollpane.getRowHeader().getWidth(); | |
146 | + } | |
147 | + c.setSize(wd, c.getHeight()); | |
148 | 148 | } |
149 | - c.setSize(wd, c.getHeight()); | |
150 | 149 | } |
151 | 150 | }); |
152 | 151 | } |
@@ -218,53 +217,14 @@ | ||
218 | 217 | */ |
219 | 218 | public void split(final MainBufferPane buffer, final int orientation, |
220 | 219 | final boolean focus) { |
221 | - final Container parent = getParent(); | |
222 | - final int size = (orientation == VERTICAL_SPLIT) ? | |
223 | - getHeight() : getWidth(); | |
224 | - | |
220 | + int direction = orientation == VERTICAL_SPLIT ? 0 : 1; | |
221 | + final NineLayout.Constraints c = new NineLayout.Constraints(direction, this); | |
225 | 222 | final RootPanel root = NineUtilities.getRootPanel(this); |
226 | 223 | root.minibuffer().acceptUserInput(); |
227 | - | |
228 | - final JSplitPane newPane = new JSplitPane(orientation, | |
229 | - content.renewWindow(), buffer.getWindow()); | |
230 | - newPane.setBorder(null); | |
231 | - | |
232 | - SwingUtilities.invokeLater(new Runnable() { | |
233 | - public void run() { | |
234 | - if (parent instanceof JPanel) { | |
235 | - executeSplit((JPanel) parent, newPane, size); | |
236 | - } else if (parent instanceof JSplitPane) { | |
237 | - executeSplit((JSplitPane) parent, newPane, size); | |
238 | - } | |
239 | - | |
240 | - copyContentViewPositionTo(buffer); | |
241 | - copyContentViewSizeTo(buffer); | |
242 | - // TODO: | |
243 | -// scrollToMakeCaretVisible(); | |
244 | - | |
245 | - if (focus) { content.requestFocusInWindow(); } | |
246 | - root.minibuffer().reset(); | |
247 | - } | |
248 | - }); | |
224 | + root.add(buffer.getWindow(), c); | |
225 | + root.minibuffer().reset(); | |
249 | 226 | } |
250 | 227 | |
251 | - private void executeSplit(JSplitPane parent, JSplitPane newPane, int size) { | |
252 | - int loc = parent.getDividerLocation(); | |
253 | - if (parent.getRightComponent() == this) { | |
254 | - parent.setRightComponent(newPane); | |
255 | - } else { | |
256 | - parent.setLeftComponent(newPane); | |
257 | - } | |
258 | - parent.setDividerLocation(loc); | |
259 | - newPane.setDividerLocation(size / 2); | |
260 | - } | |
261 | - | |
262 | - private void executeSplit(JPanel parent, JSplitPane newPane, int size) { | |
263 | - parent.remove(this); | |
264 | - parent.add(newPane, BorderLayout.CENTER); | |
265 | - newPane.setDividerLocation(size / 2); | |
266 | - } | |
267 | - | |
268 | 228 | /** |
269 | 229 | * Shows a {@code LineNumberView} component, only when |
270 | 230 | * the buffer window has a buffer of which type is |
@@ -286,19 +246,6 @@ | ||
286 | 246 | } |
287 | 247 | } |
288 | 248 | |
289 | - private void copyContentViewPositionTo(MainBufferPane m) { | |
290 | - Point p = getViewport(content).getViewPosition(); | |
291 | - getViewport(m).setViewPosition(p); | |
292 | - } | |
293 | - | |
294 | - private void copyContentViewSizeTo(MainBufferPane m) { | |
295 | - getViewport(m).setViewSize(getViewport(content).getViewSize()); | |
296 | - } | |
297 | - | |
298 | - private JViewport getViewport(MainBufferPane m) { | |
299 | - return m.getWindow().getScrollPane().getViewport(); | |
300 | - } | |
301 | - | |
302 | 249 | private MainBufferPane cloneContent() { |
303 | 250 | BufferInfo info = content.getBufferInfo(); |
304 | 251 | return info.getBufferPane(); |
@@ -18,8 +18,9 @@ | ||
18 | 18 | */ |
19 | 19 | package jp.sourceforge.nine; |
20 | 20 | |
21 | -import java.awt.BorderLayout; | |
21 | +import java.awt.Component; | |
22 | 22 | import java.awt.Frame; |
23 | +import java.awt.LayoutManager; | |
23 | 24 | import java.awt.Window; |
24 | 25 | |
25 | 26 | import javax.swing.JPanel; |
@@ -26,28 +27,15 @@ | ||
26 | 27 | import javax.swing.SwingUtilities; |
27 | 28 | |
28 | 29 | import jp.sourceforge.nine.buffer.BufferManager; |
29 | -import jp.sourceforge.nine.js.FrameSettings; | |
30 | 30 | |
31 | -import static java.awt.BorderLayout.CENTER; | |
32 | - | |
33 | 31 | public class RootPanel extends JPanel { |
34 | 32 | |
35 | 33 | private static final long serialVersionUID = -517639066431514619L; |
36 | - private MinibufferPanel minibuffer; | |
37 | 34 | private MainBufferPane currentbuffer; |
38 | 35 | |
39 | - public RootPanel(MainBufferPane bufferPane) { | |
40 | - initialize(bufferPane); | |
41 | - } | |
36 | + public RootPanel(final MainBufferPane bufferPane) { | |
37 | + setLayout(new NineLayout()); | |
42 | 38 | |
43 | - private void initialize(MainBufferPane bufferPane) { | |
44 | - | |
45 | - setLayout(new BorderLayout()); | |
46 | - | |
47 | - String l = FrameSettings.instance.getMinibufferLocation(); | |
48 | - minibuffer = new MinibufferPanel(); | |
49 | - add(minibuffer, l); | |
50 | - | |
51 | 39 | if (bufferPane == null) { |
52 | 40 | String nm = BufferManager.SCRATCH_BUFFER_NAME; |
53 | 41 | currentbuffer = MainTextPane.getNewInstance(nm); |
@@ -54,14 +42,19 @@ | ||
54 | 42 | } else { |
55 | 43 | currentbuffer = bufferPane; |
56 | 44 | } |
57 | - add(currentbuffer.getWindow(), CENTER); | |
58 | 45 | BufferManager.getInstance().addBuffer(currentbuffer); |
46 | + add(currentbuffer.getWindow()); | |
59 | 47 | |
60 | 48 | setOpaque(true); |
61 | 49 | } |
62 | 50 | |
63 | 51 | public MinibufferPanel minibuffer() { |
64 | - return minibuffer; | |
52 | + MinibufferPanel ret = null; | |
53 | + Window w = SwingUtilities.getWindowAncestor(this); | |
54 | + if (w instanceof NineFrame) { | |
55 | + ret = ((NineFrame) w).getMinibufferPanel(); | |
56 | + } | |
57 | + return ret; | |
65 | 58 | } |
66 | 59 | |
67 | 60 | public MainBufferPane currentBufferPanel() { |
@@ -74,12 +67,10 @@ | ||
74 | 67 | } |
75 | 68 | |
76 | 69 | public void setMinibufferLocation(final String location) { |
77 | - SwingUtilities.invokeLater(new Runnable() { | |
78 | - public void run() { | |
79 | - remove(minibuffer); | |
80 | - add(minibuffer, location); | |
81 | - } | |
82 | - }); | |
70 | + Window w = SwingUtilities.getWindowAncestor(RootPanel.this); | |
71 | + if (w instanceof NineFrame) { | |
72 | + ((NineFrame) w).moveMinibufferLocation(location); | |
73 | + } | |
83 | 74 | } |
84 | 75 | |
85 | 76 | private void switchFrameTitle(String bufferName) { |
@@ -89,4 +80,16 @@ | ||
89 | 80 | ((Frame) w).setTitle(t); |
90 | 81 | } |
91 | 82 | } |
83 | + | |
84 | + public void replace(Component currentComponent, Component newComponent) { | |
85 | + LayoutManager manager = getLayout(); | |
86 | + if (manager instanceof NineLayout) { | |
87 | + NineLayout m = (NineLayout) manager; | |
88 | + m.setReplacing(true); | |
89 | + remove(currentComponent); | |
90 | + add(newComponent); | |
91 | + m.setReplacing(false); | |
92 | + m.replaceLayoutComponent(currentComponent, newComponent); | |
93 | + } | |
94 | + } | |
92 | 95 | } |
@@ -0,0 +1,71 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2008-2009, mshio <mshio@users.sourceforge.jp> | |
3 | + * | |
4 | + * This program is free software: you can redistribute it and/or | |
5 | + * modify it under the terms of the GNU General Public License | |
6 | + * as published by the Free Software Foundation; either version 2 | |
7 | + * of the License, or any later version. | |
8 | + * | |
9 | + * This program is distributed in the hope that it will be useful, | |
10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | + * GNU General Public License for more details. | |
13 | + * | |
14 | + * You should have received a copy of the GNU General Public License | |
15 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | + * | |
17 | + * Require JDK 1.5 (or later) | |
18 | + */ | |
19 | + | |
20 | +package jp.sourceforge.nine; | |
21 | + | |
22 | +import java.awt.BorderLayout; | |
23 | +import java.awt.Container; | |
24 | +import java.awt.event.WindowEvent; | |
25 | + | |
26 | +import javax.swing.JFrame; | |
27 | +import javax.swing.SwingUtilities; | |
28 | + | |
29 | +import jp.sourceforge.nine.js.FrameSettings; | |
30 | + | |
31 | +public class NineFrame extends JFrame { | |
32 | + private static final long serialVersionUID = -1709487996193137453L; | |
33 | + | |
34 | + private final MinibufferPanel minibuffer; | |
35 | + | |
36 | + public NineFrame(String caption) { | |
37 | + super(caption); | |
38 | + setDefaultCloseOperation(EXIT_ON_CLOSE); | |
39 | + Container c = getContentPane(); | |
40 | + c.setLayout(new BorderLayout()); | |
41 | + minibuffer = new MinibufferPanel(); | |
42 | + String l = FrameSettings.instance.getMinibufferLocation(); | |
43 | + c.add(minibuffer, l); | |
44 | + } | |
45 | + | |
46 | + public void setRootPanel(RootPanel rootPanel) { | |
47 | + getContentPane().add(rootPanel, BorderLayout.CENTER); | |
48 | + } | |
49 | + | |
50 | + public MinibufferPanel getMinibufferPanel() { | |
51 | + return minibuffer; | |
52 | + } | |
53 | + | |
54 | + void moveMinibufferLocation(final String location) { | |
55 | + SwingUtilities.invokeLater(new Runnable() { | |
56 | + public void run() { | |
57 | + remove(minibuffer); | |
58 | + add(minibuffer, location); | |
59 | + } | |
60 | + }); | |
61 | + } | |
62 | + | |
63 | + @Override | |
64 | + protected void processWindowEvent(WindowEvent e) { | |
65 | + super.processWindowEvent(e); | |
66 | + | |
67 | + if (e.getID() == WindowEvent.WINDOW_CLOSING) { | |
68 | + Main.application.deleteFrame(this); | |
69 | + } | |
70 | + } | |
71 | +} |
@@ -1,8 +1,19 @@ | ||
1 | 1 | /* |
2 | 2 | * Copyright (C) 2008-2009, mshio <mshio@users.sourceforge.jp> |
3 | - * You can redistribute it and/or modify it under GPLv2, | |
4 | - * as published by the Free Software Foundation. | |
5 | 3 | * |
4 | + * This program is free software: you can redistribute it and/or | |
5 | + * modify it under the terms of the GNU General Public License | |
6 | + * as published by the Free Software Foundation; either version 2 | |
7 | + * of the License, or any later version. | |
8 | + * | |
9 | + * This program is distributed in the hope that it will be useful, | |
10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | + * GNU General Public License for more details. | |
13 | + * | |
14 | + * You should have received a copy of the GNU General Public License | |
15 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | + * --- | |
6 | 17 | * Require JDK 1.5 (or later) |
7 | 18 | */ |
8 | 19 | package jp.sourceforge.nine; |
@@ -18,7 +18,8 @@ | ||
18 | 18 | */ |
19 | 19 | package jp.sourceforge.nine; |
20 | 20 | |
21 | -import java.awt.event.WindowEvent; | |
21 | +import java.awt.Component; | |
22 | +import java.awt.event.ActionEvent; | |
22 | 23 | import java.io.File; |
23 | 24 | import java.lang.reflect.InvocationHandler; |
24 | 25 | import java.lang.reflect.InvocationTargetException; |
@@ -172,17 +173,7 @@ | ||
172 | 173 | * in this method. |
173 | 174 | */ |
174 | 175 | public void createFrame(MainBufferPane bufferPane) { |
175 | - JFrame f = new JFrame(APPLICATION_NAME) { | |
176 | - private static final long serialVersionUID = 5445261111336818689L; | |
177 | - | |
178 | - @Override protected void processWindowEvent(WindowEvent e) { | |
179 | - super.processWindowEvent(e); | |
180 | - | |
181 | - if (e.getID() == WindowEvent.WINDOW_CLOSING) { | |
182 | - deleteFrame(this); | |
183 | - } | |
184 | - } | |
185 | - }; | |
176 | + NineFrame f = new NineFrame(APPLICATION_NAME); | |
186 | 177 | frames.add(f); |
187 | 178 | |
188 | 179 | if (OS_TYPE == NineUtilities.OS.WINDOWS) { |
@@ -189,10 +180,8 @@ | ||
189 | 180 | changeLookAndFeel(f, WINDOWS_LOOK_AND_FEEL); |
190 | 181 | } |
191 | 182 | |
192 | - f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); | |
193 | 183 | f.setSize(600, 600); |
194 | - f.getContentPane().add(new RootPanel(bufferPane)); | |
195 | - f.setLocationByPlatform(true); | |
184 | + f.setRootPanel(new RootPanel(bufferPane)); | |
196 | 185 | f.setVisible(true); |
197 | 186 | |
198 | 187 | } |
@@ -273,7 +262,18 @@ | ||
273 | 262 | private void confirmBeforeQuit() { |
274 | 263 | // TODO |
275 | 264 | Action a = new SaveBuffersKillNineAction(); |
276 | - a.actionPerformed(null); // null ok? | |
265 | + MainBufferPane current = null; | |
266 | + JFrame f = frames.get(0); | |
267 | + Component[] comps = f.getContentPane().getComponents(); | |
268 | + for (Component c : comps) { | |
269 | + if (c instanceof RootPanel) { | |
270 | + current = ((RootPanel) c).currentBufferPanel(); | |
271 | + } | |
272 | + } | |
273 | + if (current != null) { | |
274 | + ActionEvent e = new ActionEvent(current, ActionEvent.ACTION_PERFORMED, ""); | |
275 | + a.actionPerformed(e); | |
276 | + } | |
277 | 277 | } |
278 | 278 | |
279 | 279 | /** |
@@ -0,0 +1,314 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2008-2009, mshio <mshio@users.sourceforge.jp> | |
3 | + * | |
4 | + * This program is free software: you can redistribute it and/or | |
5 | + * modify it under the terms of the GNU General Public License | |
6 | + * as published by the Free Software Foundation; either version 2 | |
7 | + * of the License, or any later version. | |
8 | + * | |
9 | + * This program is distributed in the hope that it will be useful, | |
10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | + * GNU General Public License for more details. | |
13 | + * | |
14 | + * You should have received a copy of the GNU General Public License | |
15 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | + * | |
17 | + * Require JDK 1.5 (or later) | |
18 | + */ | |
19 | + | |
20 | +package jp.sourceforge.nine; | |
21 | + | |
22 | +import java.awt.Component; | |
23 | +import java.awt.Container; | |
24 | +import java.awt.Dimension; | |
25 | +import java.awt.LayoutManager2; | |
26 | +import java.awt.Point; | |
27 | + | |
28 | +public class NineLayout implements LayoutManager2 { | |
29 | + // TODO: rename this field... | |
30 | + // This is NOT an instance of jp.sourceforge.nine.RootPanel... Confusing!! | |
31 | + // The Panel object means a metaphor of JPanel or JSplitPane. | |
32 | + // This rootPanel is a root panel of these Panels. | |
33 | + private Panel rootPanel = null; | |
34 | + // LayoutManager do not have a method to replace a specified component. | |
35 | + // Then in order to do it, the app must done remove method first, and | |
36 | + // add method next. But in the remove method, LayoutManager does change | |
37 | + // the component's layout. This flag is not to make such action done. | |
38 | + private boolean replacing = false; | |
39 | + | |
40 | + /* (non-Javadoc) | |
41 | + * @see java.awt.LayoutManager2#addLayoutComponent(java.awt.Component, java.lang.Object) | |
42 | + */ | |
43 | + public void addLayoutComponent(Component comp, Object constraints) { | |
44 | + if (replacing) { return; } | |
45 | + | |
46 | + if (rootPanel == null) { | |
47 | + rootPanel = new SinglePanel(null, comp); | |
48 | + } else if (constraints instanceof Constraints) { | |
49 | + Constraints c = (Constraints) constraints; | |
50 | + if (rootPanel instanceof SinglePanel && | |
51 | + c.currentComponent == ((SinglePanel) rootPanel).component) { | |
52 | + DoublePanel root = new DoublePanel(null, c.direction); | |
53 | + Panel p0 = new SinglePanel(root, c.currentComponent); | |
54 | + Panel p1 = new SinglePanel(root, comp); | |
55 | + root.add(p0, p1); | |
56 | + rootPanel = root; | |
57 | + } else { | |
58 | + SinglePanel s = searchPanel(rootPanel, c.currentComponent); | |
59 | + if (s != null) { | |
60 | + DoublePanel parent = (DoublePanel) s.parent; | |
61 | + boolean numIsZero = parent.child0 == s; | |
62 | + DoublePanel d = new DoublePanel(parent, c.direction); | |
63 | + Panel p0 = new SinglePanel(d, c.currentComponent); | |
64 | + Panel p1 = new SinglePanel(d, comp); | |
65 | + d.add(p0, p1); | |
66 | + if (numIsZero) { | |
67 | + parent.child0 = d; | |
68 | + } else { | |
69 | + parent.child1 = d; | |
70 | + } | |
71 | + } | |
72 | + } | |
73 | + } | |
74 | + } | |
75 | + | |
76 | + private SinglePanel searchPanel(Panel start, Component component) { | |
77 | + Panel p = start; | |
78 | + SinglePanel ret = null; | |
79 | + if (p instanceof SinglePanel) { | |
80 | + SinglePanel s = (SinglePanel) p; | |
81 | + return s.component == component ? s : null; | |
82 | + } else if (p instanceof DoublePanel) { | |
83 | + DoublePanel d = (DoublePanel) p; | |
84 | + ret = searchPanel(d.child0, component); | |
85 | + if (ret == null) { | |
86 | + ret = searchPanel(d.child1, component); | |
87 | + } | |
88 | + } | |
89 | + return ret; | |
90 | + } | |
91 | + | |
92 | + /* (non-Javadoc) | |
93 | + * @see java.awt.LayoutManager2#getLayoutAlignmentX(java.awt.Container) | |
94 | + */ | |
95 | + public float getLayoutAlignmentX(Container target) { | |
96 | + // TODO Auto-generated method stub | |
97 | + return 0; | |
98 | + } | |
99 | + | |
100 | + /* (non-Javadoc) | |
101 | + * @see java.awt.LayoutManager2#getLayoutAlignmentY(java.awt.Container) | |
102 | + */ | |
103 | + public float getLayoutAlignmentY(Container target) { | |
104 | + // TODO Auto-generated method stub | |
105 | + return 0; | |
106 | + } | |
107 | + | |
108 | + /* (non-Javadoc) | |
109 | + * @see java.awt.LayoutManager2#invalidateLayout(java.awt.Container) | |
110 | + */ | |
111 | + public void invalidateLayout(Container target) { | |
112 | + // TODO Auto-generated method stub | |
113 | + } | |
114 | + | |
115 | + /* (non-Javadoc) | |
116 | + * @see java.awt.LayoutManager2#maximumLayoutSize(java.awt.Container) | |
117 | + */ | |
118 | + public Dimension maximumLayoutSize(Container target) { | |
119 | + // TODO Auto-generated method stub | |
120 | + return null; | |
121 | + } | |
122 | + | |
123 | + /* (non-Javadoc) | |
124 | + * @see java.awt.LayoutManager#addLayoutComponent(java.lang.String, java.awt.Component) | |
125 | + */ | |
126 | + public void addLayoutComponent(String name, Component comp) { | |
127 | + // TODO Auto-generated method stub | |
128 | + } | |
129 | + | |
130 | + /* (non-Javadoc) | |
131 | + * @see java.awt.LayoutManager#layoutContainer(java.awt.Container) | |
132 | + */ | |
133 | + public void layoutContainer(Container parent) { | |
134 | + if (rootPanel == null) { return; } | |
135 | + if (rootPanel instanceof SinglePanel) { | |
136 | + Component c = ((SinglePanel) rootPanel).component; | |
137 | + c.setLocation(0, 0); | |
138 | + c.setSize(parent.getSize()); | |
139 | + } else if (rootPanel instanceof DoublePanel) { | |
140 | + layoutPanel((DoublePanel) rootPanel, new Point(0, 0), parent.getSize()); | |
141 | + } | |
142 | + } | |
143 | + | |
144 | + private void layoutPanel(DoublePanel panel, Point location, Dimension size) { | |
145 | + Panel c0 = panel.child0; | |
146 | + Panel c1 = panel.child1; | |
147 | + int d = panel.direction; | |
148 | + float f = panel.dividerLocation; | |
149 | + | |
150 | + // child0 | |
151 | + Point p0 = location; | |
152 | + Dimension d0 = (d == 0) ? | |
153 | + new Dimension(size.width, (int) (size.height * f)) : | |
154 | + new Dimension((int) (size.width * f), size.height); | |
155 | + | |
156 | + // child1 | |
157 | + Point p1; | |
158 | + Dimension d1; | |
159 | + if (d == 0) { | |
160 | + p1 = new Point(p0.x, p0.y + d0.height); | |
161 | + d1 = new Dimension(size.width, size.height - d0.height); | |
162 | + } else { | |
163 | + p1 = new Point(p0.x + d0.width, p0.y); | |
164 | + d1 = new Dimension(size.width - d0.width, size.height); | |
165 | + } | |
166 | + | |
167 | + applyLayout(c0, p0, d0); | |
168 | + applyLayout(c1, p1, d1); | |
169 | + } | |
170 | + | |
171 | + private void applyLayout(Panel panel, Point location, Dimension size) { | |
172 | + if (panel instanceof SinglePanel) { | |
173 | + Component comp = ((SinglePanel) panel).component; | |
174 | + comp.setLocation(location); | |
175 | + comp.setSize(size); | |
176 | + } else if (panel instanceof DoublePanel) { | |
177 | + layoutPanel((DoublePanel) panel, location, size); | |
178 | + } | |
179 | + } | |
180 | + | |
181 | + /* (non-Javadoc) | |
182 | + * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container) | |
183 | + */ | |
184 | + public Dimension minimumLayoutSize(Container parent) { | |
185 | + // TODO Auto-generated method stub | |
186 | + return null; | |
187 | + } | |
188 | + | |
189 | + /* (non-Javadoc) | |
190 | + * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container) | |
191 | + */ | |
192 | + public Dimension preferredLayoutSize(Container parent) { | |
193 | + // TODO Auto-generated method stub | |
194 | + return null; | |
195 | + } | |
196 | + | |
197 | + /* (non-Javadoc) | |
198 | + * @see java.awt.LayoutManager#removeLayoutComponent(java.awt.Component) | |
199 | + */ | |
200 | + public void removeLayoutComponent(Component comp) { | |
201 | + if (replacing) { return; } | |
202 | + | |
203 | + SinglePanel found = searchPanel(rootPanel, comp); | |
204 | + if (found != null) { | |
205 | + removeComponent(found); | |
206 | + } | |
207 | + } | |
208 | + | |
209 | + private void removeComponent(SinglePanel found) { | |
210 | + DoublePanel parent = (DoublePanel) found.parent; | |
211 | + if (parent == null) { | |
212 | + rootPanel = null; | |
213 | + } else { | |
214 | + int childID = parent.child0 == found ? 1 : 0; | |
215 | + Panel child = parent.getChild(childID); | |
216 | + DoublePanel grandparent = (DoublePanel) parent.parent; | |
217 | + if (grandparent == null) { | |
218 | + rootPanel = child; | |
219 | + child.changeParent(null); | |
220 | + } else { | |
221 | + grandparent.replaceChild(grandparent.child0 == parent ? 0 : 1, child); | |
222 | + } | |
223 | + | |
224 | + } | |
225 | + } | |
226 | + | |
227 | + public void replaceLayoutComponent(Component currentComp, Component newComp) { | |
228 | + newComp.setLocation(currentComp.getLocation()); | |
229 | + newComp.setSize(currentComp.getSize()); | |
230 | + SinglePanel found = searchPanel(rootPanel, currentComp); | |
231 | + | |
232 | + if (found != null) { | |
233 | + SinglePanel newPanel = new SinglePanel(found.parent, newComp); | |
234 | + DoublePanel parent = (DoublePanel) found.parent; | |
235 | + if (parent == null) { | |
236 | + rootPanel = newPanel; | |
237 | + } else { | |
238 | + int childID = parent.child0 == found ? 0 : 1; | |
239 | + if (childID == 0) { | |
240 | + parent.child0 = newPanel; | |
241 | + } else { | |
242 | + parent.child1 = newPanel; | |
243 | + } | |
244 | + } | |
245 | + } | |
246 | + } | |
247 | + | |
248 | + public void setReplacing(boolean isReplacing) { | |
249 | + replacing = isReplacing; | |
250 | + } | |
251 | + | |
252 | + | |
253 | + abstract class Panel { | |
254 | + Panel parent; | |
255 | + | |
256 | + Panel(Panel parent) { | |
257 | + this.parent = parent; | |
258 | + } | |
259 | + | |
260 | + void changeParent(Panel parent) { | |
261 | + this.parent = parent; | |
262 | + } | |
263 | + } | |
264 | + | |
265 | + class SinglePanel extends Panel { | |
266 | + Component component; | |
267 | + | |
268 | + SinglePanel(Panel parent, Component component) { | |
269 | + super(parent); | |
270 | + this.component = component; | |
271 | + } | |
272 | + } | |
273 | + | |
274 | + class DoublePanel extends Panel { | |
275 | + int direction = 0; | |
276 | + float dividerLocation = 0.5f; | |
277 | + Panel child0; | |
278 | + Panel child1; | |
279 | + | |
280 | + DoublePanel(Panel parent, int direction) { | |
281 | + super(parent); | |
282 | + this.direction = direction; | |
283 | + } | |
284 | + | |
285 | + void add(Panel child0, Panel child1) { | |
286 | + this.child0 = child0; | |
287 | + this.child1 = child1; | |
288 | + } | |
289 | + | |
290 | + Panel getChild(int id) { | |
291 | + return id == 0 ? child0 : id == 1 ? child1 : null; | |
292 | + } | |
293 | + | |
294 | + void replaceChild(final int id, final Panel p) { | |
295 | + p.changeParent(this); | |
296 | + if (id == 0) { | |
297 | + child0 = p; | |
298 | + } else if (id == 1) { | |
299 | + child1 = p; | |
300 | + } | |
301 | + } | |
302 | + } | |
303 | + | |
304 | + | |
305 | + public static class Constraints { | |
306 | + final int direction; | |
307 | + final Component currentComponent; | |
308 | + | |
309 | + public Constraints(int direction, Component currentComponent) { | |
310 | + this.direction = direction; | |
311 | + this.currentComponent = currentComponent; | |
312 | + } | |
313 | + } | |
314 | +} |
@@ -10,9 +10,11 @@ | ||
10 | 10 | |
11 | 11 | import java.lang.reflect.InvocationTargetException; |
12 | 12 | import java.lang.reflect.Method; |
13 | + | |
13 | 14 | import javax.swing.JComponent; |
14 | 15 | import javax.swing.event.DocumentEvent; |
15 | 16 | import javax.swing.text.BadLocationException; |
17 | +import javax.swing.text.Caret; | |
16 | 18 | import javax.swing.text.DefaultEditorKit; |
17 | 19 | import javax.swing.text.Document; |
18 | 20 | import javax.swing.text.Element; |
@@ -29,10 +31,11 @@ | ||
29 | 31 | private final boolean wordWrap; |
30 | 32 | private int tabBase; |
31 | 33 | private Color unselected; |
34 | + private Color selected; | |
32 | 35 | private boolean widthChanging; |
33 | 36 | // TODO: how to define this color |
34 | 37 | private static final Color CONTROL_CHAR_COLOR = Color.decode("#8B0000"); |
35 | - private Method drawChars = null; | |
38 | + private Method drawChars = null; | |
36 | 39 | |
37 | 40 | public NineWrappedPlainView(Element element, boolean wordWrap) { |
38 | 41 | super(element, wordWrap); |
@@ -55,6 +58,9 @@ | ||
55 | 58 | JTextComponent host = (JTextComponent) getContainer(); |
56 | 59 | unselected = (host.isEnabled()) ? |
57 | 60 | host.getForeground() : host.getDisabledTextColor(); |
61 | + Caret c = host.getCaret(); | |
62 | + selected = c.isSelectionVisible() && host.getHighlighter() != null ? | |
63 | + host.getSelectedTextColor() : unselected; | |
58 | 64 | super.paint(g, a); |
59 | 65 | } |
60 | 66 |
@@ -82,12 +88,21 @@ | ||
82 | 88 | @Override |
83 | 89 | protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1) |
84 | 90 | throws BadLocationException { |
85 | - int ret = x; | |
86 | - g.setColor(unselected); | |
91 | + return drawText(g, x, y, p0, p1, unselected); | |
92 | + } | |
93 | + | |
94 | + @Override | |
95 | + protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1) | |
96 | + throws BadLocationException { | |
97 | + return drawText(g, x, y, p0, p1, selected); | |
98 | + } | |
99 | + | |
100 | + private int drawText(Graphics g, int x, int y, int p0, int p1, Color c) | |
101 | + throws BadLocationException { | |
102 | + g.setColor(c); | |
87 | 103 | Segment s = new Segment(); |
88 | 104 | getDocument().getText(p0, p1 - p0, s); |
89 | - ret = drawTabbedText(s, x, y, g, p0); | |
90 | - return ret; | |
105 | + return drawTabbedText(s, x, y, g, p0); | |
91 | 106 | } |
92 | 107 | |
93 | 108 | private String getNewlineCode() { |
@@ -268,7 +283,7 @@ | ||
268 | 283 | if (n > 0) { |
269 | 284 | View[] added = new View[n]; |
270 | 285 | for (int i = 0; i < n; i++) { |
271 | - added[i] = new WrappedLine(e.getElement(i)); | |
286 | + added[i] = new NineWrappedLine(e.getElement(i)); | |
272 | 287 | } |
273 | 288 | replace(0, 0, added); |
274 | 289 | } |
@@ -283,7 +298,7 @@ | ||
283 | 298 | Element[] addedElems = ec.getChildrenAdded(); |
284 | 299 | View[] added = new View[addedElems.length]; |
285 | 300 | for (int i = 0; i < addedElems.length; i++) { |
286 | - added[i] = new WrappedLine(addedElems[i]); | |
301 | + added[i] = new NineWrappedLine(addedElems[i]); | |
287 | 302 | } |
288 | 303 | replace(ec.getIndex(), removedElems.length, added); |
289 | 304 |
@@ -336,9 +351,9 @@ | ||
336 | 351 | * state of it's own and sharing the state of the outer class |
337 | 352 | * with it's sibblings. |
338 | 353 | */ |
339 | - class WrappedLine extends View { | |
354 | + class NineWrappedLine extends View { | |
340 | 355 | |
341 | - WrappedLine(Element elem) { | |
356 | + NineWrappedLine(Element elem) { | |
342 | 357 | super(elem); |
343 | 358 | lineCount = -1; |
344 | 359 | } |
@@ -422,7 +437,7 @@ | ||
422 | 437 | * @see View#modelToView |
423 | 438 | */ |
424 | 439 | public Shape modelToView(int pos, Shape a, Position.Bias b) |
425 | - throws BadLocationException { | |
440 | + throws BadLocationException { | |
426 | 441 | Rectangle alloc = a.getBounds(); |
427 | 442 | alloc.height = getFontMetrics().getHeight(); |
428 | 443 | alloc.width = 1; |
@@ -103,7 +103,7 @@ | ||
103 | 103 | } |
104 | 104 | } |
105 | 105 | return textComponent != null && |
106 | - rootPanel != null && minibuffer != null; | |
106 | + rootPanel != null && minibuffer != null; | |
107 | 107 | } |
108 | 108 | } |
109 | 109 |
@@ -18,6 +18,7 @@ | ||
18 | 18 | import java.awt.print.Printable; |
19 | 19 | import java.awt.print.PrinterException; |
20 | 20 | import java.awt.print.PrinterJob; |
21 | +import java.io.File; | |
21 | 22 | import java.util.LinkedList; |
22 | 23 | |
23 | 24 | import javax.swing.text.JTextComponent; |
@@ -42,7 +43,9 @@ | ||
42 | 43 | JTextComponent t = getTextComponent(e); |
43 | 44 | PrinterJob job = PrinterJob.getPrinterJob(); |
44 | 45 | if (t instanceof MainTextPane) { |
45 | - String nm = ((MainTextPane) t).getBufferFile().getName(); | |
46 | + MainTextPane textPane = (MainTextPane) t; | |
47 | + File f = textPane.getBufferFile(); | |
48 | + String nm = f == null ? textPane.getBufferName() : f.getName(); | |
46 | 49 | job.setJobName(nm); |
47 | 50 | } |
48 | 51 | PageFormat f0 = new PageFormat(); |
@@ -89,6 +92,7 @@ | ||
89 | 92 | Font font = textComponent.getFont(); |
90 | 93 | FontMetrics fm = g.getFontMetrics(font); |
91 | 94 | g.setFont(font); |
95 | + | |
92 | 96 | int lineHeight = fm.getHeight(); |
93 | 97 | |
94 | 98 | if (ranges.isEmpty()) { makeTextToLineList(g); } |
@@ -202,4 +206,5 @@ | ||
202 | 206 | int startPosition() { return startPosition; } |
203 | 207 | int endPosition() { return endPosition; } |
204 | 208 | } |
209 | + | |
205 | 210 | } |
@@ -18,12 +18,12 @@ | ||
18 | 18 | */ |
19 | 19 | package jp.sourceforge.nine.action; |
20 | 20 | |
21 | -import java.awt.Component; | |
22 | 21 | import java.awt.event.ActionEvent; |
23 | 22 | import java.io.File; |
24 | 23 | import java.lang.reflect.Constructor; |
25 | 24 | import java.lang.reflect.InvocationTargetException; |
26 | 25 | |
26 | +import javax.swing.JComponent; | |
27 | 27 | import javax.swing.JSplitPane; |
28 | 28 | import javax.swing.SwingUtilities; |
29 | 29 |
@@ -33,7 +33,6 @@ | ||
33 | 33 | import jp.sourceforge.nine.MainTableData; |
34 | 34 | import jp.sourceforge.nine.MainTablePane; |
35 | 35 | import jp.sourceforge.nine.RootPanel; |
36 | -import jp.sourceforge.nine.action.util.BufferSwitcher; | |
37 | 36 | import jp.sourceforge.nine.buffer.BufferManager; |
38 | 37 | import jp.sourceforge.nine.util.NineUtilities; |
39 | 38 |
@@ -40,6 +39,7 @@ | ||
40 | 39 | public class ListBuffersAction extends ScriptableTextAction { |
41 | 40 | private static final long serialVersionUID = 4857774137409224921L; |
42 | 41 | public static final String ACTION_NAME = "list-buffers"; |
42 | + public static final String BUFFER_NAME = "*Buffer List*"; | |
43 | 43 | |
44 | 44 | public ListBuffersAction() { |
45 | 45 | super(ACTION_NAME); |
@@ -47,32 +47,25 @@ | ||
47 | 47 | |
48 | 48 | @Override |
49 | 49 | public void perform(ActionEvent e) { |
50 | - final RootPanel p = NineUtilities.getRootPanel(getTextComponent(e)); | |
51 | - final MainBufferPane mb = p.currentBufferPanel(); | |
52 | - // TODO: | |
53 | - String name = "jp.sourceforge.nine.bufferlist.BufferlistTableData"; | |
54 | - ClassLoader loader = Main.getPluginClassLoader(); | |
50 | + Object o = e.getSource(); | |
51 | + final JComponent comp = o instanceof JComponent ? (JComponent) o : null; | |
52 | + // TODO: when this component is null, the app should throw any errors? | |
53 | + if (comp == null) { return; } | |
54 | + final RootPanel rootPanel = NineUtilities.getRootPanel(comp); | |
55 | + final MainBufferPane mb = rootPanel.currentBufferPanel(); | |
56 | + | |
55 | 57 | try { |
56 | - Class<? extends MainTableData> clazz = | |
57 | - Class.forName(name, true, loader).asSubclass(MainTableData.class); | |
58 | - Constructor<? extends MainTableData> c = | |
59 | - clazz.getConstructor(File.class); | |
60 | - MainTableData d = c.newInstance((File) null); | |
61 | - BufferManager m = BufferManager.getInstance(); | |
62 | - String nm = "*Buffer List*"; | |
63 | - m.removeBuffer(nm); | |
64 | - final MainTablePane t = MainTablePane.getInstance(nm, null, d); | |
65 | - m.addBuffer(t); | |
58 | + MainTableData data = getBufferListTableData(); | |
59 | + BufferManager manager = BufferManager.getInstance(); | |
60 | + manager.removeBuffer(BUFFER_NAME); | |
61 | + final MainTablePane table = MainTablePane.getInstance(BUFFER_NAME, null, data); | |
62 | + manager.addBuffer(table); | |
66 | 63 | SwingUtilities.invokeLater(new Runnable() { |
67 | 64 | public void run() { |
68 | - p.minibuffer().acceptUserInput(); | |
69 | - switchBuffer(p, t); | |
70 | - SwingUtilities.invokeLater(new Runnable() { | |
71 | - public void run() { | |
72 | - p.minibuffer().reset(); | |
73 | - mb.requestFocusInWindow(); | |
74 | - } | |
75 | - }); | |
65 | + rootPanel.minibuffer().acceptUserInput(); | |
66 | + showBuffer(rootPanel, table); | |
67 | + rootPanel.minibuffer().reset(); | |
68 | + mb.requestFocusInWindow(); | |
76 | 69 | } |
77 | 70 | }); |
78 | 71 | } catch (ClassNotFoundException ex) { |
@@ -93,23 +86,25 @@ | ||
93 | 86 | } |
94 | 87 | } |
95 | 88 | |
96 | - private void switchBuffer(final RootPanel rootPanel, | |
89 | + private MainTableData getBufferListTableData() | |
90 | + throws ClassNotFoundException, SecurityException, NoSuchMethodException, | |
91 | + IllegalArgumentException, InstantiationException, | |
92 | + IllegalAccessException, InvocationTargetException { | |
93 | + // TODO: how to get the name of table data class of buffer list plugin. | |
94 | + String name = "jp.sourceforge.nine.bufferlist.BufferlistTableData"; | |
95 | + ClassLoader loader = Main.getPluginClassLoader(); | |
96 | + Class<? extends MainTableData> clazz = | |
97 | + Class.forName(name, true, loader).asSubclass(MainTableData.class); | |
98 | + Constructor<? extends MainTableData> c = clazz.getConstructor(File.class); | |
99 | + return c.newInstance((File) null); | |
100 | + } | |
101 | + | |
102 | + private void showBuffer(final RootPanel rootPanel, | |
97 | 103 | final MainTablePane tablePane) { |
98 | 104 | |
99 | 105 | BufferWindow w = rootPanel.currentBufferPanel().getWindow(); |
100 | - if (w.getParent() instanceof JSplitPane) { | |
101 | - execute(rootPanel, tablePane); | |
102 | - } else { | |
103 | - w.split(tablePane, JSplitPane.VERTICAL_SPLIT, false); | |
104 | - } | |
106 | + // TODO: when already having a splitted window, | |
107 | + // the app should replace its contents into buffer list. | |
108 | + w.split(tablePane, JSplitPane.VERTICAL_SPLIT, false); | |
105 | 109 | } |
106 | - | |
107 | - private void execute(RootPanel root, MainBufferPane requestedBuffer) { | |
108 | - Component n = NineUtilities.getNextComponent(root); | |
109 | - | |
110 | - if (n instanceof MainBufferPane) { | |
111 | - Runnable r = new BufferSwitcher(requestedBuffer, (MainBufferPane) n, false); | |
112 | - SwingUtilities.invokeLater(r); | |
113 | - } | |
114 | - } | |
115 | 110 | } |
@@ -18,13 +18,7 @@ | ||
18 | 18 | */ |
19 | 19 | package jp.sourceforge.nine.action.util; |
20 | 20 | |
21 | -import java.awt.BorderLayout; | |
22 | -import java.awt.Container; | |
23 | -import java.awt.Dimension; | |
24 | - | |
25 | 21 | import javax.swing.JComponent; |
26 | -import javax.swing.JPanel; | |
27 | -import javax.swing.JSplitPane; | |
28 | 22 | import javax.swing.SwingUtilities; |
29 | 23 | |
30 | 24 | import jp.sourceforge.nine.BufferWindow; |
@@ -63,36 +57,10 @@ | ||
63 | 57 | } |
64 | 58 | |
65 | 59 | public void run() { |
66 | - BufferWindow bp = bufferToBeReplaced.getWindow(); | |
67 | - Container p = bp.getParent(); | |
60 | + final BufferWindow bp = bufferToBeReplaced.getWindow(); | |
68 | 61 | |
69 | - // User focus could escap here... | |
70 | 62 | rootPanel.minibuffer().acceptUserInput(); |
71 | - | |
72 | - if (p instanceof JPanel) { | |
73 | - p.remove(bp); | |
74 | - p.add(bufferPane.getWindow(), BorderLayout.CENTER); | |
75 | - } else if (p instanceof JSplitPane) { | |
76 | - final JSplitPane splitter = (JSplitPane) p; | |
77 | - BufferWindow toBeReplaced = bufferToBeReplaced.getWindow(); | |
78 | - | |
79 | - final int loc = splitter.getDividerLocation(); | |
80 | - Dimension d = toBeReplaced.getSize(); | |
81 | - boolean right = splitter.getRightComponent() == toBeReplaced; | |
82 | - bufferPane.getWindow().setSize(d); | |
83 | - if (right) { | |
84 | - splitter.setRightComponent(bufferPane.getWindow()); | |
85 | - } else { | |
86 | - splitter.setLeftComponent(bufferPane.getWindow()); | |
87 | - } | |
88 | - splitter.setDividerLocation(loc); | |
89 | - SwingUtilities.invokeLater(new Runnable() { | |
90 | - public void run() { | |
91 | - splitter.setDividerLocation(loc); | |
92 | - } | |
93 | - }); | |
94 | - } | |
95 | - | |
63 | + rootPanel.replace(bp, bufferPane.getWindow()); | |
96 | 64 | rootPanel.minibuffer().reset(); |
97 | 65 | |
98 | 66 | SwingUtilities.invokeLater(new Runnable() { |
@@ -1,8 +1,19 @@ | ||
1 | 1 | /* |
2 | 2 | * Copyright (C) 2008-2009, mshio <mshio@users.sourceforge.jp> |
3 | - * You can redistribute it and/or modify it under GPLv2, | |
4 | - * as published by the Free Software Foundation. | |
5 | 3 | * |
4 | + * This program is free software: you can redistribute it and/or | |
5 | + * modify it under the terms of the GNU General Public License | |
6 | + * as published by the Free Software Foundation; either version 2 | |
7 | + * of the License, or any later version. | |
8 | + * | |
9 | + * This program is distributed in the hope that it will be useful, | |
10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | + * GNU General Public License for more details. | |
13 | + * | |
14 | + * You should have received a copy of the GNU General Public License | |
15 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | + * --- | |
6 | 17 | * Require JDK 1.5 (or later) |
7 | 18 | */ |
8 | 19 | package jp.sourceforge.nine.action.util; |
@@ -9,9 +20,12 @@ | ||
9 | 20 | |
10 | 21 | import java.awt.Component; |
11 | 22 | import java.awt.Container; |
23 | +import java.awt.Dimension; | |
24 | +import java.awt.Point; | |
12 | 25 | |
13 | 26 | import javax.swing.SwingUtilities; |
14 | 27 | |
28 | +import jp.sourceforge.nine.BufferWindow; | |
15 | 29 | import jp.sourceforge.nine.MainBufferPane; |
16 | 30 | import jp.sourceforge.nine.MinibufferPanel; |
17 | 31 | import jp.sourceforge.nine.RootPanel; |
@@ -20,12 +34,11 @@ | ||
20 | 34 | public class KillBufferCommand implements Command<Void> { |
21 | 35 | final String bufferName; |
22 | 36 | final RootPanel rootPanel; |
23 | - boolean minibufferReset = true; | |
24 | - boolean requestFocus = true; | |
37 | + final boolean minibufferReset; | |
38 | + final boolean requestFocus; | |
25 | 39 | |
26 | 40 | public KillBufferCommand(String bufferName, RootPanel rootPanel) { |
27 | - this.bufferName = bufferName; | |
28 | - this.rootPanel = rootPanel; | |
41 | + this(bufferName, rootPanel, true, true); | |
29 | 42 | } |
30 | 43 | |
31 | 44 | public KillBufferCommand(String bufferName, RootPanel rootPanel, |
@@ -47,27 +60,20 @@ | ||
47 | 60 | } |
48 | 61 | if (next.equals("*Buffer List*")) { next = bm.peekInBuffer(1); } |
49 | 62 | |
50 | - MainBufferPane nextBuffer = bm.getBuffer(next); | |
51 | - if (requestFocus) { | |
52 | - SwingUtilities.invokeLater(new BufferSwitcher(rootPanel, nextBuffer)); | |
63 | + final Point current = getCurrentBufferLocation(); | |
64 | + switchBuffer(rootPanel, rootPanel, bufferName, next); | |
65 | + if (! bufferName.equals(BufferManager.SCRATCH_BUFFER_NAME)) { | |
66 | + bm.removeBuffer(bufferName); | |
53 | 67 | } |
54 | - final String nextBufferName = next; | |
55 | 68 | SwingUtilities.invokeLater(new Runnable() { |
56 | 69 | public void run() { |
57 | - switchBuffer(rootPanel, rootPanel, bufferName, nextBufferName); | |
58 | - if (! bufferName.equals(BufferManager.SCRATCH_BUFFER_NAME)) { | |
59 | - bm.removeBuffer(bufferName); | |
60 | - } | |
61 | - if (minibufferReset) { | |
62 | - MinibufferPanel m = rootPanel.minibuffer(); | |
63 | - m.reset(); | |
64 | - m.setTextToLabel(" "); | |
65 | - } | |
66 | 70 | if (requestFocus) { |
67 | - MainBufferPane b = rootPanel.currentBufferPanel(); | |
68 | - b.requestFocusInWindow(); | |
69 | - b.getWindow().repaint(); | |
71 | + Component c = rootPanel.getComponentAt(current); | |
72 | + if (c instanceof BufferWindow) { | |
73 | + ((BufferWindow) c).getContent().requestFocusInWindow(); | |
74 | + } | |
70 | 75 | } |
76 | + if (minibufferReset) { rootPanel.minibuffer().reset(); } | |
71 | 77 | } |
72 | 78 | }); |
73 | 79 |
@@ -74,6 +80,13 @@ | ||
74 | 80 | return null; |
75 | 81 | } |
76 | 82 | |
83 | + private Point getCurrentBufferLocation() { | |
84 | + BufferWindow w = rootPanel.currentBufferPanel().getWindow(); | |
85 | + Point point = w.getLocation(); | |
86 | + Dimension size = w.getSize(); | |
87 | + return new Point(point.x + size.width / 2, point.y + size.height / 2); | |
88 | + } | |
89 | + | |
77 | 90 | private void processLastBuffer() { |
78 | 91 | if (requestFocus) { |
79 | 92 | rootPanel.currentBufferPanel().requestFocusInWindow(); |
@@ -81,11 +94,10 @@ | ||
81 | 94 | if (minibufferReset) { |
82 | 95 | MinibufferPanel m = rootPanel.minibuffer(); |
83 | 96 | m.reset(); |
84 | - m.setTextToLabel(" "); | |
85 | 97 | } |
86 | 98 | } |
87 | 99 | |
88 | - private void switchBuffer(RootPanel root, Container container, | |
100 | + private void switchBuffer(final RootPanel root, Container container, | |
89 | 101 | String current, String next) { |
90 | 102 | Component[] his = container.getComponents(); |
91 | 103 | if (his == null) return; |
@@ -96,8 +108,9 @@ | ||
96 | 108 | if (something instanceof MainBufferPane) { |
97 | 109 | MainBufferPane finding = (MainBufferPane) something; |
98 | 110 | if (finding.getBufferName().equals(current)) { |
111 | + final MainBufferPane buffer = bm.getBuffer(next); | |
99 | 112 | Runnable r = |
100 | - new BufferSwitcher(bm.getBuffer(next), finding, false); | |
113 | + new BufferSwitcher(buffer, finding, false); | |
101 | 114 | SwingUtilities.invokeLater(r); |
102 | 115 | } |
103 | 116 | } else if (something instanceof Container) { |
@@ -18,18 +18,12 @@ | ||
18 | 18 | */ |
19 | 19 | package jp.sourceforge.nine.action; |
20 | 20 | |
21 | -import java.awt.BorderLayout; | |
22 | 21 | import java.awt.Component; |
23 | 22 | import java.awt.event.ActionEvent; |
24 | 23 | |
25 | 24 | import javax.swing.JComponent; |
26 | -import javax.swing.JSplitPane; | |
27 | 25 | import javax.swing.SwingUtilities; |
28 | -import javax.swing.text.BadLocationException; | |
29 | -import javax.swing.text.JTextComponent; | |
30 | 26 | |
31 | -import jp.sourceforge.nine.MainBufferPane; | |
32 | -import jp.sourceforge.nine.BufferWindow; | |
33 | 27 | import jp.sourceforge.nine.RootPanel; |
34 | 28 | import jp.sourceforge.nine.util.NineUtilities; |
35 | 29 |
@@ -42,7 +36,6 @@ | ||
42 | 36 | * @author mshio |
43 | 37 | */ |
44 | 38 | public class DeleteOtherWindowsAction extends ScriptableTextAction { |
45 | - | |
46 | 39 | private static final long serialVersionUID = -5407099002160023082L; |
47 | 40 | public static final String ACTION_NAME = "delete-other-windows"; |
48 | 41 |
@@ -59,42 +52,19 @@ | ||
59 | 52 | * @param e the action event |
60 | 53 | */ |
61 | 54 | @Override |
62 | - public void perform(ActionEvent e) { | |
63 | - Object o = e.getSource(); | |
64 | - RootPanel root = NineUtilities.getRootPanel((JComponent) o); | |
65 | - SwingUtilities.invokeLater(new OtherWindowsDeleter(root)); | |
66 | - } | |
67 | -} | |
68 | - | |
69 | - | |
70 | -class OtherWindowsDeleter implements Runnable { | |
71 | - RootPanel root; | |
72 | - OtherWindowsDeleter(RootPanel root) { | |
73 | - this.root = root; | |
74 | - } | |
75 | - | |
76 | - public void run() { | |
77 | - for (Component c : root.getComponents()) { | |
78 | - if (c instanceof BufferWindow || c instanceof JSplitPane) { | |
79 | - root.remove(c); | |
80 | - break; | |
81 | - } | |
82 | - } | |
83 | - final MainBufferPane m = root.currentBufferPanel(); | |
84 | - root.minibuffer().acceptUserInput(); | |
85 | - root.add(m.getWindow(), BorderLayout.CENTER); | |
86 | - if (m instanceof JTextComponent) { | |
87 | - JTextComponent t = (JTextComponent)m; | |
88 | - try { | |
89 | - t.scrollRectToVisible(t.modelToView(t.getCaretPosition())); | |
90 | - } catch (BadLocationException e) { | |
91 | - e.printStackTrace(); | |
92 | - } | |
93 | - } | |
94 | - root.minibuffer().reset(); | |
55 | + public void perform(final ActionEvent e) { | |
56 | + final Object o = e.getSource(); | |
57 | + final RootPanel rootPanel = NineUtilities.getRootPanel((JComponent) o); | |
58 | + rootPanel.minibuffer().acceptUserInput(); | |
95 | 59 | SwingUtilities.invokeLater(new Runnable() { |
96 | 60 | public void run() { |
97 | - m.requestFocusInWindow(); | |
61 | + final Component[] components = rootPanel.getComponents(); | |
62 | + for (final Component c : components) { | |
63 | + rootPanel.remove(c); | |
64 | + } | |
65 | + rootPanel.add(rootPanel.currentBufferPanel().getWindow()); | |
66 | + rootPanel.repaint(); | |
67 | + rootPanel.minibuffer().reset(); | |
98 | 68 | } |
99 | 69 | }); |
100 | 70 | } |
@@ -18,21 +18,15 @@ | ||
18 | 18 | */ |
19 | 19 | package jp.sourceforge.nine.action; |
20 | 20 | |
21 | -import java.awt.Component; | |
22 | -import java.awt.Container; | |
23 | 21 | import java.awt.event.ActionEvent; |
24 | 22 | |
25 | 23 | import javax.swing.JComponent; |
26 | -import javax.swing.JSplitPane; | |
27 | 24 | |
28 | -import jp.sourceforge.nine.BufferWindow; | |
29 | 25 | import jp.sourceforge.nine.MainBufferPane; |
30 | 26 | import jp.sourceforge.nine.RootPanel; |
31 | 27 | import jp.sourceforge.nine.util.MessageUtility; |
32 | 28 | import jp.sourceforge.nine.util.NineUtilities; |
33 | 29 | |
34 | -import static javax.swing.SwingUtilities.invokeLater; | |
35 | - | |
36 | 30 | /** |
37 | 31 | * An action to delete the selected window. |
38 | 32 | * |
@@ -50,17 +44,19 @@ | ||
50 | 44 | |
51 | 45 | @Override |
52 | 46 | public void perform(ActionEvent e) { |
53 | - JComponent c = getTextComponent(e); | |
47 | + Object o = e.getSource(); | |
48 | + JComponent c = o instanceof JComponent ? (JComponent) o : null; | |
54 | 49 | if (c != null) { |
55 | 50 | final RootPanel r = NineUtilities.getRootPanel(c); |
56 | 51 | final MainBufferPane current = r.currentBufferPanel(); |
57 | - final Container parent = current.getWindow().getParent(); | |
58 | - if (parent instanceof JSplitPane) { | |
59 | - Runnable run = new WindowDeleter(current, (JSplitPane) parent); | |
60 | - invokeLater(run); | |
61 | - invokeLater(new Runnable() { public void run() { r.repaint(); } }); | |
52 | + | |
53 | + if (r.getComponentCount() == 1) { | |
54 | + showCannotDeleteMessage(r); | |
62 | 55 | } else { |
63 | - showCannotDeleteMessage(r); | |
56 | + r.minibuffer().acceptUserInput(); | |
57 | + r.remove(current.getWindow()); | |
58 | + r.repaint(); | |
59 | + r.minibuffer().reset(); | |
64 | 60 | } |
65 | 61 | } |
66 | 62 | } |
@@ -71,71 +67,4 @@ | ||
71 | 67 | root.minibuffer().reset(s); |
72 | 68 | } |
73 | 69 | |
74 | - | |
75 | - static class WindowDeleter implements Runnable { | |
76 | - final JSplitPane splitPane; | |
77 | - final MainBufferPane currentPane; | |
78 | - | |
79 | - WindowDeleter(MainBufferPane current, JSplitPane splitPane) { | |
80 | - this.splitPane = splitPane; | |
81 | - this.currentPane = current; | |
82 | - } | |
83 | - | |
84 | - public void run() { | |
85 | - final Component other = getOtherComponent(); | |
86 | - final RootPanel root = NineUtilities.getRootPanel(splitPane); | |
87 | - root.minibuffer().acceptUserInput(); | |
88 | - // usually, other is an instance of buffer window. | |
89 | - if (other instanceof BufferWindow) { | |
90 | - deleteWhenOtherIsWindow(root, (BufferWindow) other); | |
91 | - } else if (other instanceof JSplitPane) { | |
92 | - deleteWhenOtherIsSplit(root, (JSplitPane) other); | |
93 | - } | |
94 | - } | |
95 | - | |
96 | - private void deleteWhenOtherIsWindow(final RootPanel root, BufferWindow other) { | |
97 | - splitPane.remove(currentPane.getWindow()); | |
98 | - final Container pane = splitPane.getParent(); | |
99 | - final boolean isSplitPane = pane instanceof JSplitPane; | |
100 | - final JSplitPane split = isSplitPane ? (JSplitPane) pane : null; | |
101 | - final int location = isSplitPane ? split.getDividerLocation() : 0; | |
102 | - pane.remove(splitPane); | |
103 | - pane.add(other); | |
104 | - if (isSplitPane) { split.setDividerLocation(location); } | |
105 | - final MainBufferPane next = other.getContent(); | |
106 | - invokeLater(new Runnable() { | |
107 | - public void run() { | |
108 | - root.setCurrentBufferPanel(next); | |
109 | - root.minibuffer().reset(); | |
110 | - invokeLater(new Runnable() { | |
111 | - public void run() { next.requestFocusInWindow(); } | |
112 | - }); | |
113 | - } | |
114 | - }); | |
115 | - } | |
116 | - | |
117 | - private void deleteWhenOtherIsSplit(RootPanel root, JSplitPane other) { | |
118 | - final Component next = NineUtilities.getNextComponent(root); | |
119 | - Container parent = splitPane.getParent(); | |
120 | - parent.remove(splitPane); | |
121 | - parent.add(other); | |
122 | - invokeLater(new Runnable() { | |
123 | - public void run() { next.requestFocusInWindow(); } | |
124 | - }); | |
125 | - } | |
126 | - | |
127 | - /** | |
128 | - * Returns a component which is not a deleting window | |
129 | - * on the split pane. | |
130 | - * @return component which is not a deleting window | |
131 | - */ | |
132 | - private Component getOtherComponent() { | |
133 | - Component other = splitPane.getTopComponent(); | |
134 | - if (other == currentPane.getWindow()) { | |
135 | - other = splitPane.getBottomComponent(); | |
136 | - } | |
137 | - return other; | |
138 | - } | |
139 | - } | |
140 | - | |
141 | 70 | } |
@@ -23,7 +23,7 @@ | ||
23 | 23 | |
24 | 24 | import javax.swing.Action; |
25 | 25 | import javax.swing.ActionMap; |
26 | -import javax.swing.text.JTextComponent; | |
26 | +import javax.swing.JComponent; | |
27 | 27 | |
28 | 28 | import jp.sourceforge.nine.MinibufferPanel; |
29 | 29 | import jp.sourceforge.nine.RootPanel; |
@@ -127,9 +127,11 @@ | ||
127 | 127 | } |
128 | 128 | |
129 | 129 | private RootPanel getRootPanel(ActionEvent e) { |
130 | - // This text component means the minibuffer. | |
131 | - JTextComponent t = getTextComponent(e); | |
132 | - return rootPanel = t == null ? null : NineUtilities.getRootPanel(t); | |
130 | + Object o = e.getSource(); | |
131 | + if (o instanceof JComponent) { | |
132 | + return rootPanel = NineUtilities.getRootPanel((JComponent) o); | |
133 | + } | |
134 | + return rootPanel = null; | |
133 | 135 | } |
134 | 136 | |
135 | 137 | private MinibufferPanel getMinibufferPanel(ActionEvent e) { |
@@ -136,9 +138,4 @@ | ||
136 | 138 | RootPanel r = getRootPanel(e); |
137 | 139 | return r == null ? null : r.minibuffer(); |
138 | 140 | } |
139 | - | |
140 | - | |
141 | -// @Retention(RetentionPolicy.RUNTIME) | |
142 | -// @Target(ElementType.FIELD) | |
143 | -// protected @interface PromptLabelKey { } | |
144 | 141 | } |
@@ -44,7 +44,6 @@ | ||
44 | 44 | * unlike original Emacs, as the need arises. |
45 | 45 | */ |
46 | 46 | public class FindFileSuggestionAction extends MinibufferPopupAction { |
47 | - | |
48 | 47 | private static final long serialVersionUID = 4143362895935712636L; |
49 | 48 | |
50 | 49 | private FindFileSuggestionPopup popup = null; |
@@ -54,9 +53,7 @@ | ||
54 | 53 | if (! p.initialize(e)) { return; } |
55 | 54 | String text = p.minibuffer.getTextFromInputArea(); |
56 | 55 | if (text == null) { return; } |
57 | - | |
58 | 56 | if (expandVariables(text, p.minibuffer)) { return; } |
59 | - | |
60 | 57 | int sep = text.lastIndexOf(File.separatorChar); |
61 | 58 | if (sep != -1) { |
62 | 59 | suggest(text, sep, p); |
@@ -24,6 +24,7 @@ | ||
24 | 24 | import java.awt.FocusTraversalPolicy; |
25 | 25 | import java.awt.GraphicsEnvironment; |
26 | 26 | import java.awt.Rectangle; |
27 | +import java.awt.Window; | |
27 | 28 | import java.io.BufferedReader; |
28 | 29 | import java.io.File; |
29 | 30 | import java.io.FileNotFoundException; |
@@ -36,10 +37,12 @@ | ||
36 | 37 | import javax.swing.Icon; |
37 | 38 | import javax.swing.ImageIcon; |
38 | 39 | import javax.swing.JComponent; |
40 | +import javax.swing.JFrame; | |
39 | 41 | import javax.swing.SwingUtilities; |
40 | 42 | import javax.swing.UIManager; |
41 | 43 | |
42 | 44 | import jp.sourceforge.nine.MainBufferPane; |
45 | +import jp.sourceforge.nine.MinibufferPanel; | |
43 | 46 | import jp.sourceforge.nine.RootPanel; |
44 | 47 | import jp.sourceforge.nine.js.FrameSettings; |
45 | 48 |
@@ -63,10 +66,28 @@ | ||
63 | 66 | */ |
64 | 67 | public static RootPanel getRootPanel(JComponent component) { |
65 | 68 | Container c = component.getParent(); |
69 | + if (c == null) { return null; } | |
66 | 70 | do { |
67 | - if (c instanceof RootPanel) return (RootPanel)c; | |
71 | + if (c instanceof RootPanel) { | |
72 | + return (RootPanel) c; | |
73 | + } else if (c instanceof MinibufferPanel) { | |
74 | + return getRootPanelFromMinibuffer((MinibufferPanel) c); | |
75 | + } | |
68 | 76 | } while ((c = c.getParent()) != null); |
77 | + return null; | |
78 | + } | |
69 | 79 | |
80 | + private static RootPanel getRootPanelFromMinibuffer(MinibufferPanel minibuffer) { | |
81 | + Window w = SwingUtilities.getWindowAncestor(minibuffer); | |
82 | + if (w instanceof JFrame) { | |
83 | + Container container = ((JFrame) w).getContentPane(); | |
84 | + Component[] comp = container.getComponents(); | |
85 | + for (Component c : comp) { | |
86 | + if (c instanceof RootPanel) { | |
87 | + return (RootPanel) c; | |
88 | + } | |
89 | + } | |
90 | + } | |
70 | 91 | return null; |
71 | 92 | } |
72 | 93 |
@@ -55,6 +55,7 @@ | ||
55 | 55 | 'split-window-vertically': text['split-window-vertically'], |
56 | 56 | 'split-window-horizontally': text['split-window-horizontally'], |
57 | 57 | 'delete-other-windows': text['delete-other-windows'], |
58 | + 'delete-window': text['delete-window'], | |
58 | 59 | 'other-window': text['other-window'], |
59 | 60 | 'kill-buffer': text['kill-buffer'], |
60 | 61 | 'execute-extended-command': text['execute-extended-command'], |