-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
copy selected classes from net.sf.swinglib
- Loading branch information
kdgregory
committed
Feb 28, 2015
1 parent
75b57b8
commit 31eaa6c
Showing
8 changed files
with
1,210 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
src/main/java/net/sf/kdgcommons/swing/AsynchronousOperation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright Keith D Gregory | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package net.sf.kdgcommons.swing; | ||
|
||
import javax.swing.SwingUtilities; | ||
|
||
|
||
/** | ||
* A base class for implementing operations that need to run on their own thread | ||
* and report back to the event thread. Unlike Sun's <code>SwingWorker</code> | ||
* class, this object does not spawn its own thread. Instead, it must be passed | ||
* to a program-created thread, or better, a threadpool. | ||
* <p> | ||
* To use, subclass and pass an instance to your background thread(pool). | ||
* <p> | ||
* You must implement at least the {@link #performOperation} method, which is | ||
* executed on the operation thread. This method may return a single object, | ||
* or throw any exception type. Depending on how it completes (return/throw), | ||
* one of {@link #onSuccess}, {@link #onFailure} will then be executed on the | ||
* event thread. | ||
* | ||
* @since 1.1.0 | ||
**/ | ||
|
||
public abstract class AsynchronousOperation<T> | ||
implements Runnable | ||
{ | ||
public final void run() | ||
{ | ||
try | ||
{ | ||
final T result = performOperation(); | ||
SwingUtilities.invokeLater(new Runnable() | ||
{ | ||
public void run() | ||
{ | ||
onComplete(); | ||
onSuccess(result); | ||
} | ||
}); | ||
} | ||
catch (final Throwable e) | ||
{ | ||
SwingUtilities.invokeLater(new Runnable() | ||
{ | ||
public void run() | ||
{ | ||
onComplete(); | ||
onFailure(e); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* The concrete class implements this method, which is executed on the | ||
* non-event thread. It is permitted to return a value that is then passed | ||
* to the code running on the event thread. It is also permitted to throw | ||
* any exception type. | ||
*/ | ||
protected abstract T performOperation() | ||
throws Exception; | ||
|
||
|
||
/** | ||
* This method is invoked on the event thread when the operation completes, | ||
* <em>regardless of whether it succeeded or failed</em>. It exists so that | ||
* subclasses can manage user feedback (such as resetting a busy cursor). | ||
*/ | ||
protected void onComplete() | ||
{ | ||
// default implementation does nothing | ||
} | ||
|
||
|
||
/** | ||
* This method is invoked on the event thread after a successful call to | ||
* <code>performOperation()</code>. Application code typically overrides | ||
* to do something with that result. | ||
*/ | ||
protected void onSuccess(T result) | ||
{ | ||
// default implementation does nothing | ||
} | ||
|
||
|
||
/** | ||
* This method is invoked on the event thread if <code>performOperation() | ||
* </code> threw an exception. Application code typically overrides | ||
* to do something with that exception. | ||
*/ | ||
protected void onFailure(Throwable e) | ||
{ | ||
throw new RuntimeException(e); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright Keith D Gregory | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package net.sf.kdgcommons.swing; | ||
|
||
import java.awt.Toolkit; | ||
import java.awt.datatransfer.Clipboard; | ||
import java.awt.datatransfer.ClipboardOwner; | ||
import java.awt.datatransfer.DataFlavor; | ||
import java.awt.datatransfer.Transferable; | ||
import java.awt.datatransfer.UnsupportedFlavorException; | ||
import java.io.IOException; | ||
|
||
|
||
/** | ||
* Provides a simple mechanism for interacting with the system clipboard, | ||
* where you want to copy/paste a restricted set of data types and don't | ||
* want to hook up with a component. Particularly useful for application- | ||
* level actions. | ||
* | ||
* @since 1.1.0 | ||
*/ | ||
public class ClipManager | ||
{ | ||
/** | ||
* Puts the specified string on the system clipboard. | ||
*/ | ||
public static void putString(String str) | ||
{ | ||
Toolkit.getDefaultToolkit() | ||
.getSystemClipboard() | ||
.setContents(new StringClip(str), new ClipCallback()); | ||
} | ||
|
||
|
||
//---------------------------------------------------------------------------- | ||
// Internals | ||
//---------------------------------------------------------------------------- | ||
|
||
/** | ||
* An object that's notified when the clipboard contents changes. We | ||
* don't really care about that notification, but the clipboard requires | ||
* a callback. | ||
*/ | ||
private static class ClipCallback | ||
implements ClipboardOwner | ||
{ | ||
public void lostOwnership(Clipboard clipboard, Transferable contents) | ||
{ | ||
// nothing happening here | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Used to package a string for the clipboard. | ||
*/ | ||
private static class StringClip | ||
implements Transferable | ||
{ | ||
private String _str; | ||
private DataFlavor _myFlavor; | ||
|
||
public StringClip(String str) | ||
{ | ||
_str = str; | ||
_myFlavor = DataFlavor.stringFlavor; | ||
} | ||
|
||
public Object getTransferData(DataFlavor flavor) | ||
throws UnsupportedFlavorException, IOException | ||
{ | ||
if (!flavor.equals(_myFlavor)) | ||
return null; | ||
|
||
return _str; | ||
} | ||
|
||
public DataFlavor[] getTransferDataFlavors() | ||
{ | ||
return new DataFlavor[] { _myFlavor }; | ||
} | ||
|
||
public boolean isDataFlavorSupported(DataFlavor flavor) | ||
{ | ||
return flavor.equals(_myFlavor); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// Copyright Keith D Gregory | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package net.sf.kdgcommons.swing; | ||
|
||
import java.awt.Dimension; | ||
import java.awt.Rectangle; | ||
import java.awt.Toolkit; | ||
import java.awt.Window; | ||
|
||
|
||
/** | ||
* A collection of static utility methods for Swing apps. | ||
* | ||
* @since 1.1.0 | ||
*/ | ||
public class SwingUtil | ||
{ | ||
/** | ||
* Centers the passed window (dialog or frame) on the screen and makes | ||
* it visible. This is typically used to display the main window for | ||
* an application. | ||
*/ | ||
public static void centerAndShow(Window window) | ||
{ | ||
center(window); | ||
window.setVisible(true); | ||
} | ||
|
||
|
||
/** | ||
* Centers the passed window (dialog or frame) within the second window | ||
* and makes it visible. This is typically used to display a dialog. | ||
* <p> | ||
* The second window may be null, in which case the first is centered within | ||
* the screen. This is a convenience for ownerless dialogs. | ||
*/ | ||
public static void centerAndShow(Window window, Window inWindow) | ||
{ | ||
center(window, inWindow); | ||
window.setVisible(true); | ||
} | ||
|
||
|
||
/** | ||
* Updates the passed window's position to center it with respect to the | ||
* screen. May be called before or after the window is made visible (but | ||
* remember to call <code>pack()</code> first!). | ||
* <p> | ||
* Deals with multi-monitor setups via the following hack: if the screen | ||
* size reported by the default toolkit has a width:height ration > 2:1, | ||
* then the width is divided by 2. This works well for 1, 2, or 3 screen | ||
* desktops: the window will appear in the left screen of a 2-screen | ||
* setup, in the middle of a 3-screen setup. | ||
* <p> | ||
* If the window is larger than the screen size, it's positioned at the | ||
* top-left corner. Hopefully the user will be able to shrink it. | ||
*/ | ||
public static void center(Window window) | ||
{ | ||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); | ||
int width = screenSize.width; | ||
int height = screenSize.height; | ||
if (width > height * 2) | ||
width /= 2; | ||
|
||
center(window, new Rectangle(0, 0, width, height), false); | ||
} | ||
|
||
|
||
/** | ||
* Updates the first window's position to center it with respect to the | ||
* second window. If the first window is larger than the second, it will | ||
* be offset to the top/left as needed, but not exceeding the bounds of | ||
* the screen. | ||
* <p> | ||
* The second window may be null, in which case the first is centered within | ||
* the screen. This is a convenience for ownerless dialogs. | ||
*/ | ||
public static void center(Window window, Window inWindow) | ||
{ | ||
if (inWindow == null) | ||
center(window); | ||
else | ||
center(window, inWindow.getBounds(), true); | ||
} | ||
|
||
|
||
/** | ||
* Centers a window within a specified space. If the window is larger than | ||
* the width/height of the space, it may optionally overflow: its X and Y | ||
* will be less than those passed. However, it is not allowed to overflow | ||
* to negative coordinates. | ||
*/ | ||
private static void center(Window window, Rectangle bounds, boolean allowOverflow) | ||
{ | ||
Dimension windowSize = window.getSize(); | ||
|
||
int offsetX = (bounds.width - windowSize.width) / 2; | ||
if ((offsetX < 0) && !allowOverflow) | ||
offsetX = 0; | ||
|
||
int x = bounds.x + offsetX; | ||
if (x < 0) | ||
x = 0; | ||
|
||
int offsetY = (bounds.height - windowSize.height) / 2; | ||
if ((offsetY < 0) && !allowOverflow) | ||
offsetY = 0; | ||
|
||
int y = bounds.y + offsetY; | ||
if (y < 0) | ||
y = 0; | ||
|
||
window.setLocation(x, y); | ||
} | ||
} |
Oops, something went wrong.