missing added files from merge

From-SVN: r86958
This commit is contained in:
Graydon Hoare 2004-09-02 06:58:08 +00:00
parent 9969aaf67e
commit 61341707b3
30 changed files with 10202 additions and 0 deletions

View File

@ -0,0 +1,109 @@
/* GThreadMutex.java -- Implements a mutex object for glib's gthread
abstraction, for use with GNU Classpath's --portable-native-sync option.
This is used in gthread-jni.c
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.awt.peer.gtk;
/** Implements a mutex object for glib's gthread
abstraction, for use with GNU Classpath's --portable-native-sync option.
This is used in gthread-jni.c.
We use this object to implement the POSIX semantics for Mutexes. They are
needed are needed for the function vector that is passed to glib's
g_thread subpackage's initialization function.
The GThreadMutex object itself serves as the Real Lock; if code has
entered the monitor for this GThreadMutex object (in Java language, if
it's synchronized on this object) then it holds the lock that this object
represents.
@author Steven Augart
May, 2004
*/
class GThreadMutex
{
/** Might "lock" be locked? Is anyone waiting
to get that lock? How long is the queue?
If zero, nobody holds a lock on this GThreadMutex object, and nobody is
trying to get one. Before someone attempts to acquire a lock on this
object, they must increment potentialLockers. After they release their
lock on this object, they must decrement potentialLockers.
Access to this field is guarded by synchronizing on the object
<code>lockForPotentialLockers</code>.
After construction, we only access this field via JNI.
*/
volatile int potentialLockers;
/** An object to synchronize to if you want to examine or modify the
<code>potentialLockers</code> field. Only hold this lock for brief
moments, just long enough to check or set the value of
<code>lockForPotentialLockers</code>.
We use this representation so that g_thread_mutex_trylock() will work
with the POSIX semantics. This is the only case in which you ever hold a
lock on <code>lockForPotentialLockers</code> while trying to get another
lock -- if you are the mutex_trylock() implementation, and you have just
checked that <code>potentialLockers</code> has the value zero. In that
case, mutex_trylock() holds the lock on lockForPotentialLockers so that
another thread calling mutex_trylock() or mutex_lock() won't increment
potentialLockers after we've checked it and before we've gained the lock
on the POSIX mutex. Of course, in that case the operation of gaining
the POSIX lock itself will succeed immediately, and once it has
succeeded, trylock releases lockForPotentialLockers right away,
incremented to 1 (one).
After construction, we only access this field via JNI.
*/
Object lockForPotentialLockers;
GThreadMutex()
{
potentialLockers = 0;
lockForPotentialLockers = new Object();
}
}
// Local Variables:
// c-file-style: "gnu"
// End:

View File

@ -0,0 +1,302 @@
/* GThreadNativeMethodRunner.java -- Implements pthread_create(), under
glib's gthread abstraction, for use with GNU Classpath's
--portable-native-sync option.
This is used by gthread-jni.c
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.awt.peer.gtk;
import java.lang.ref.WeakReference;
import java.util.Set;
import java.util.Collections;
import java.util.HashSet;
/** Implements pthread_create(), under glib's gthread abstraction, for use
with GNU Classpath's --portable-native-sync option. This is used in
gthread-jni.c
Also implements a registry for threads, mapping Thread objects to small
integers. The registry uses weak references for threads that aren't
joinable, so that they will be garbage collected.
There are a number of possible alternative implementations.
The rest of this comment consists of an answer to a question that was
raised on the commit-classpath mailing list:
Mark Wielaard wrote:
> Can't we assume that jobject and gpointer are both (void *) so we don't
> need the int <-> Thread (global jobject ref) mapping?
> Maybe there are platforms where jobject and gpointer aren't the same,
> but I guess that is pretty unlikely.
I agree with you on the pointer size issues. A gpointer is a void *, so
it's certainly guaranteed to be at least as large as any other
pointer. And a jobject is implicitly an opaque pointer (in Jikes RVM, we
use small integers, but we coerce them into the representation of a
pointer).
The int <==> Thread mapping addresses a different issue. I realize that I
did not document this properly (two and a half lines in thread_create),
and the point is subtle (at least to me; took me a while to figure out).
The int => Thread mapping always returns jobjects that are local
references, not global ones. This is because Thread objects need to be
able to go away and be garbage collected after the thread they refer to
has died.
If we keep a global object reference to a thread, then when do we delete
that global object reference? We have an answer in the case of GThread
objects that were explicitly created with the joinable attribute. It is
safe for us to maintain a global reference to any joinable thread, since
the joinable thread must linger (even if only in a zombie state)
until it's explicitly joined via a g_thread_join() call. The global ref
could be cleaned up at that point too.
However, in the case of GThreads that were created non-joinable by
g_thread_create(), and in the case of Java threads that were created
within pure Java code (not via g_thread_create()), we don't want them to
linger forever, and there is no way to tell when the last reference
to such threads needs to expire. In the case of this application -- AWT
with GTK peers -- it would probably be safe anyway, since there are not
very many threads we create, but I was going for correctness even in the
case of long-running programs that might set up and tear down AWT
interfaces many times.
So, I duplicated the POSIX thread-ID semantics. The thread ID of a
non-joinable thread remains valid as long as that thread is still alive.
Once that thread dies, the old thread ID may be reused at any moment. And
that's why the array indexed by thread ID numbers is an array of weak
references.
That's also why the int => Thread jobject mapping function always returns
local references, since global references would lock the Thread in memory
forever.
I would dearly love there to be a cleaner solution. I dislike the
repeated dips from C code into Java that are necessary to look up thread
ID numbers. If anyone can think of one, I'm all ears.
*/
class GThreadNativeMethodRunner
extends Thread
{
/** The C function pointer that was passed to g_thread_create().
Specifically, this the numeric address of an object of
C type "void *(*funcPtr)(void *funcArg)".
*/
private final long funcPtr;
/** The argument for the function "funcPtr(funcArg)". */
private final long funcArg;
GThreadNativeMethodRunner(long funcPtr, long funcArg, boolean joinable)
{
this.funcPtr = funcPtr;
this.funcArg = funcArg;
if (joinable)
registerSelfJoinable();
}
public void run()
{
nativeRun(funcPtr, funcArg);
}
private native void nativeRun(long funcPtr, long funcArg);
/** THREADS is an array of threads, indexed by thread ID codes. Not sure
whether this is the "best" approach but it does make it O(1) to look up a
thread by its ID.
Zero is a valid thread ID code. Any negative number is invalid.
Possible future fixes (TODO?)
- The THREADS array will only grow. probably not a problem.
But we could keep count when nulling entries and shrink when we have
lots of nulls at the end. Probably not worth it. --mjw
- Could make this a set of Object; see the comment on "joinable" below.
The initial size of 17 is just a starting point. Any number will do,
including zero.
*/
private static WeakReference[] threads = new WeakReference[17];
/** Used by threadToThreadID, below. Returns the registration number of
the newly-registered thread.
*/
private static synchronized int registerThread(Thread t)
{
int i;
for (i = 0; i < threads.length; ++i)
{
WeakReference ref = threads[i];
if (ref == null)
break; // found an empty spot.
}
if (i == threads.length)
{
/* expand the array */
WeakReference[] bigger = new WeakReference[threads.length * 2];
System.arraycopy(threads, 0, bigger, 0, threads.length);
threads = bigger;
}
threads[i] = new WeakReference(t);
return i;
}
/** Look up the Thread ID # for a Thread. Assign a Thread ID # if none
exists. This is a general routine for handling all threads, including
the VM's main thread, if appropriate.
Runs in O(n/2) time.
We can't just issue a threadID upon thread creation. If we were to do
that, not all threads would have a threadID, because not all threads
are launched by GThreadNativeMethodRunner.
*/
static synchronized int threadToThreadID(Thread t)
{
for (int i = 0; i < threads.length; ++i )
{
if (threads[i] == null)
continue;
Thread referent = (Thread) threads[i].get();
if (referent == null)
{
threads[i] = null; // Purge the dead WeakReference.
continue;
}
if (referent.equals(t))
return i;
} // for()
/* No match found. */
return registerThread(t);
}
/** @param threadID Must be a non-negative integer.
Used to return null if the thread number was out of range or if
the thread was unregistered. Now we throw an exception.
Possible Alternative Interface: We could go back to returning null in
some sort of check-free mode, so code that calls this function must
be prepared to get null.
*/
static Thread threadIDToThread(int threadID)
throws IllegalArgumentException
{
if (threadID < 0)
throw new IllegalArgumentException("Received a negative threadID, "
+ threadID);
if (threadID >= threads.length)
throw new IllegalArgumentException("Received a threadID (" + threadID
+ ") higher than was"
+ " ever issued");
/* Note: if the user is using a stale reference, things will just
break. We might end up getting a different thread than the one
expected.
TODO: Add an error-checking mode where the user's problems with threads
are announced. For instance, if the user asks for the thread
associated with a threadID that was never issued, we could print a
warning or even abort.
TODO: Consider optionally disabling all of the error-checking we
already have; it probably slows down the implementation. We could
just return NULL. This is just the reverse of the above TODO item.
*/
WeakReference threadRef = threads[threadID];
if (threadRef == null)
throw new IllegalArgumentException("Asked to look up a stale or unissued"
+ "threadID (" + threadID + ")" );
Thread referent = (Thread) threadRef.get();
if (referent == null)
throw new IllegalArgumentException ("Asked to look up a stale threadID ("
+ threadID + ")");
return referent;
}
/** Joinable threads need a hard reference, so that they won't go away when
they die. That is because their thread IDs need to stay valid until the
thread is joined via thread_join(threadID). Joinable threads have to be
explicitly joined before they are allowed to go away completely.
Possible Alternative Implementation: Eliminate the Joinable set. When
calling getThreadIDFromThread() you know whether or not the thread
is joinable. So just store the Thread itself in the threads array?
Make that array an Object array and check with instanceof. This
looks cleaner and more robust to me and it saves a native -> Java
call. But instanceof might be expensive. --mjw
*/
private static final Set joinable =
Collections.synchronizedSet(new HashSet());
/** Only called from the constructor. */
private void registerSelfJoinable()
{
joinable.add(this);
}
/** This method is only called from JNI, and only after we have succeeded in
a thread_join() operation. */
static void deRegisterJoinable(Thread thread)
{
joinable.remove(thread);
}
}
// Local Variables:
// c-file-style: "gnu"
// End:

View File

@ -0,0 +1,115 @@
/* AbstractSpinnerModel.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing;
import java.util.EventListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
/**
* AbstractSpinnerModel
* @author Ka-Hing Cheung
* @version 1.0
*/
public abstract class AbstractSpinnerModel implements SpinnerModel
{
private ChangeEvent changeEvent = new ChangeEvent(this);
protected EventListenerList listenerList = new EventListenerList();
/**
* Creates an <code>AbstractSpinnerModel</code>.
*/
public AbstractSpinnerModel()
{
}
/**
* Adds a <code>ChangeListener</code>.
*
* @param listener the listener to add
*/
public void addChangeListener(ChangeListener listener)
{
listenerList.add(ChangeListener.class, listener);
}
/**
* Gets all the listeners that are of a particular type.
*
* @param c the type of listener
* @return the listeners that are of the specific type
*/
public EventListener[] getListeners(Class c)
{
return listenerList.getListeners(c);
}
/**
* Gets all the <code>ChangeListener</code>s.
*
* @return all the <code>ChangeListener</code>s
*/
public ChangeListener[] getChangeListeners()
{
return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
}
/**
* Remove a particular listener.
*
* @param listener the listener to remove
*/
public void removeChangeListener(ChangeListener listener)
{
listenerList.remove(ChangeListener.class, listener);
}
/**
* Fires a <code>ChangeEvent</code> to all the <code>ChangeListener</code>s
* added to this model
*/
protected void fireStateChanged()
{
ChangeListener[] listeners = getChangeListeners();
for(int i = 0; i < listeners.length; ++i)
listeners[i].stateChanged(changeEvent);
}
}

View File

@ -0,0 +1,482 @@
/* JSpinner.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.EventListener;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import javax.swing.plaf.SpinnerUI;
/**
* A JSpinner is a component which typically contains a numeric value and a
* way to manipulate the value.
*
* @author Ka-Hing Cheung
* @version 1.0
*/
public class JSpinner extends JComponent
{
/**
* DOCUMENT ME!
*/
public static class StubEditor extends JLabel implements ChangeListener
{
/** DOCUMENT ME! */
private JLabel label;
/** DOCUMENT ME! */
private JButton up;
/** DOCUMENT ME! */
private JButton down;
/** DOCUMENT ME! */
private JSpinner spinner;
/**
* Creates a new StubEditor object.
*
* @param spinner DOCUMENT ME!
*/
public StubEditor(JSpinner spinner)
{
this.spinner = spinner;
setBorder(new EtchedBorder());
setHorizontalAlignment(SwingConstants.TRAILING);
stateChanged(null); /* fill in the label */
}
/**
* DOCUMENT ME!
*
* @param evt DOCUMENT ME!
*/
public void stateChanged(ChangeEvent evt)
{
setText(String.valueOf(spinner.getValue()));
}
}
/**
* DOCUMENT ME!
*/
public static class DefaultEditor extends JPanel implements ChangeListener,
PropertyChangeListener,
LayoutManager
{
/**
* Creates a new DefaultEditor object.
*
* @param spinner DOCUMENT ME!
*/
public DefaultEditor(JSpinner spinner)
{
spinner.addChangeListener(this);
} /* TODO */
/**
* DOCUMENT ME!
*/
public void commitEdit()
{
} /* TODO */
/**
* DOCUMENT ME!
*
* @param spinner DOCUMENT ME!
*/
public void dismiss(JSpinner spinner)
{
spinner.removeChangeListener(this);
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public JFormattedTextField getTextField()
{
return null;
} /* TODO */
/**
* DOCUMENT ME!
*
* @param parent DOCUMENT ME!
*/
public void layoutContainer(Container parent)
{
} /* TODO */
/**
* DOCUMENT ME!
*
* @param parent DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Dimension minimumLayoutSize(Container parent)
{
return null;
} /* TODO */
/**
* DOCUMENT ME!
*
* @param parent DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Dimension preferredLayoutSize(Container parent)
{
return null;
} /* TODO */
/**
* DOCUMENT ME!
*
* @param evt DOCUMENT ME!
*/
public void propertyChange(PropertyChangeEvent evt)
{
} /* TODO */
/**
* DOCUMENT ME!
*
* @param evt DOCUMENT ME!
*/
public void stateChanged(ChangeEvent evt)
{
} /* TODO */
/* no-ops */
public void removeLayoutComponent(Component child)
{
}
/**
* DOCUMENT ME!
*
* @param name DOCUMENT ME!
* @param child DOCUMENT ME!
*/
public void addLayoutComponent(String name, Component child)
{
}
}
/**
* DOCUMENT ME!
*/
public static class NumberEditor extends DefaultEditor
{
/**
* Creates a new NumberEditor object.
*
* @param spinner DOCUMENT ME!
*/
public NumberEditor(JSpinner spinner)
{
super(spinner);
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public DecimalFormat getFormat()
{
return null;
}
}
/** DOCUMENT ME! */
private SpinnerModel model;
/** DOCUMENT ME! */
private JComponent editor;
/** DOCUMENT ME! */
private EventListenerList listenerList = new EventListenerList();
/** DOCUMENT ME! */
private ChangeListener listener = new ChangeListener()
{
public void stateChanged(ChangeEvent evt)
{
fireStateChanged();
}
};
/**
* Creates a JSpinner with <code>SpinnerNumberModel</code>
*
* @see javax.swing.SpinnerNumberModel
*/
public JSpinner()
{
this(new SpinnerNumberModel());
}
/**
* Creates a JSpinner with the specific model and sets the default editor
*
* @param model DOCUMENT ME!
*/
public JSpinner(SpinnerModel model)
{
this.model = model;
model.addChangeListener(listener);
setEditor(createEditor(model));
updateUI();
}
/**
* If the editor is <code>JSpinner.DefaultEditor</code>, then forwards the
* call to it, otherwise do nothing.
*
* @throws ParseException DOCUMENT ME!
*/
public void commitEdit() throws ParseException
{
if (editor instanceof DefaultEditor)
((DefaultEditor) editor).commitEdit();
}
/**
* Gets the current editor
*
* @return the current editor
*
* @see #setEditor
*/
public JComponent getEditor()
{
return editor;
}
/**
* Changes the current editor to the new editor. This methods should remove
* the old listeners (if any) and adds the new listeners (if any).
*
* @param editor the new editor
*
* @throws IllegalArgumentException DOCUMENT ME!
*
* @see #getEditor
*/
public void setEditor(JComponent editor)
{
if (editor == null)
throw new IllegalArgumentException("editor may not be null");
if (this.editor instanceof DefaultEditor)
((DefaultEditor) editor).dismiss(this);
else if (this.editor instanceof ChangeListener)
removeChangeListener((ChangeListener) this.editor);
if (editor instanceof ChangeListener)
addChangeListener((ChangeListener) editor);
this.editor = editor;
}
/**
* Gets the underly model.
*
* @return the underly model
*/
public SpinnerModel getModel()
{
return model;
}
/**
* Gets the next value without changing the current value.
*
* @return the next value
*
* @see javax.swing.SpinnerModel#getNextValue
*/
public Object getNextValue()
{
return model.getNextValue();
}
/**
* Gets the previous value without changing the current value.
*
* @return the previous value
*
* @see javax.swing.SpinnerModel#getPreviousValue
*/
public Object getPreviousValue()
{
return model.getPreviousValue();
}
/**
* Gets the <code>SpinnerUI</code> that handles this spinner
*
* @return the <code>SpinnerUI</code>
*/
public SpinnerUI getUI()
{
return (SpinnerUI) ui;
}
/**
* Gets the current value of the spinner, according to the underly model,
* not the UI.
*
* @return the current value
*
* @see javax.swing.SpinnerModel#getValue
*/
public Object getValue()
{
return model.getValue();
}
/**
* DOCUMENT ME!
*
* @param value DOCUMENT ME!
*/
public void setValue(Object value)
{
model.setValue(value);
}
/**
* This method returns a name to identify which look and feel class will be
* the UI delegate for this spinner.
*
* @return The UIClass identifier. "SpinnerUI"
*/
public String getUIClassID()
{
return "SpinnerUI";
}
/**
* This method resets the spinner's UI delegate to the default UI for the
* current look and feel.
*/
public void updateUI()
{
setUI((SpinnerUI) UIManager.getUI(this));
}
/**
* This method sets the spinner's UI delegate.
*
* @param ui The spinner's UI delegate.
*/
public void setUI(SpinnerUI ui)
{
super.setUI(ui);
}
/**
* Adds a <code>ChangeListener</code>
*
* @param listener the listener to add
*/
public void addChangeListener(ChangeListener listener)
{
listenerList.add(ChangeListener.class, listener);
}
/**
* Remove a particular listener
*
* @param listener the listener to remove
*/
public void removeChangeListener(ChangeListener listener)
{
listenerList.remove(ChangeListener.class, listener);
}
/**
* Gets all the <code>ChangeListener</code>s
*
* @return all the <code>ChangeListener</code>s
*/
public ChangeListener[] getChangeListeners()
{
return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
}
/**
* Fires a <code>ChangeEvent</code> to all the <code>ChangeListener</code>s
* added to this <code>JSpinner</code>
*/
protected void fireStateChanged()
{
ChangeEvent evt = new ChangeEvent(this);
ChangeListener[] listeners = getChangeListeners();
for (int i = 0; i < listeners.length; ++i)
listeners[i].stateChanged(evt);
}
/**
* Creates an editor for this <code>JSpinner</code>. Really, it should be a
* <code>JSpinner.DefaultEditor</code>, but since that should be
* implemented by a JFormattedTextField, and one is not written, I am just
* using a dummy one backed by a JLabel.
*
* @param model DOCUMENT ME!
*
* @return the default editor
*/
protected JComponent createEditor(SpinnerModel model)
{
return new StubEditor(this);
} /* TODO */}

View File

@ -0,0 +1,241 @@
/* SpinnerNumberModel.java --
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing;
/**
* SpinnerNumberModel
*
* @author Ka-Hing Cheung
* @version 1.0
*/
public class SpinnerNumberModel extends AbstractSpinnerModel
{
/** DOCUMENT ME! */
private Number value;
/** DOCUMENT ME! */
private Comparable minimum;
/** DOCUMENT ME! */
private Comparable maximum;
/** DOCUMENT ME! */
private Number stepSize;
/**
* Creates a <code>SpinnerNumberModel</code> with initial value 0, step 1,
* and no maximum nor minimum.
*/
public SpinnerNumberModel()
{
this(new Integer(0), null, null, new Integer(1));
}
/**
* Creates a <code>SpinnerNumberModel</code> with double precision
*
* @param value the initial value
* @param minimum the minimum value
* @param maximum the maximum value
* @param stepSize the step size
*/
public SpinnerNumberModel(double value, double minimum, double maximum,
double stepSize)
{
this(new Double(value), new Double(minimum), new Double(maximum),
new Double(stepSize));
}
/**
* Creates a <code>SpinnerNumberModel</code> with integer precision
*
* @param value the initial value
* @param minimum the minimum value
* @param maximum the maximum value
* @param stepSize the step size
*/
public SpinnerNumberModel(int value, int minimum, int maximum, int stepSize)
{
this(new Integer(value), new Integer(minimum), new Integer(maximum),
new Integer(stepSize));
}
/**
* Creates a <code>SpinnerNumberModel</code> with <code>Number</code>s and
* <code>Comparable</code>s.
*
* @param value the initial value
* @param minimum the minimum value, if null there's no minimum
* @param maximum the maximum value, if null there's no maximum
* @param stepSize the step size
*
* @throws IllegalArgumentException if minimum &lt;= value &lt;= maximum
* does not hold
*/
public SpinnerNumberModel(Number value, Comparable minimum,
Comparable maximum, Number stepSize)
{
if (stepSize == null)
throw new IllegalArgumentException("stepSize may not be null");
if (value == null)
throw new IllegalArgumentException("value may not be null");
if (minimum != null)
{
if (minimum.compareTo(value) > 0)
throw new IllegalArgumentException("minimum is not <= value");
}
else
minimum = new Comparable()
{
public int compareTo(Object obj)
{
return -1;
}
};
if (maximum != null)
{
if (maximum.compareTo(value) < 0)
throw new IllegalArgumentException("maximum is not >= value");
}
else
maximum = new Comparable()
{
public int compareTo(Object obj)
{
return 1;
}
};
this.value = value;
this.stepSize = stepSize;
this.minimum = minimum;
this.maximum = maximum;
}
/**
* Sets the new value and fire a change event
*
* @param value the new value
*
* @throws IllegalArgumentException if minimum &lt;= value &lt;= maximum
* does not hold
*/
public void setValue(Object value)
{
if (! (value instanceof Number))
throw new IllegalArgumentException("value must be a Number");
this.value = (Number) value;
fireStateChanged();
}
/**
* Gets the current value
*
* @return the current value
*/
public Object getValue()
{
return value;
}
/**
* Gets the next value without changing the current value, or null if the
* current value is maximum.
*
* @return the next value
*/
public Object getNextValue()
{
Number num;
if (value instanceof Double)
num = new Double(value.doubleValue() + stepSize.doubleValue());
else if (value instanceof Float)
num = new Double(value.floatValue() + stepSize.floatValue());
else if (value instanceof Long)
num = new Long(value.longValue() + stepSize.longValue());
else if (value instanceof Integer)
num = new Integer(value.intValue() + stepSize.intValue());
else if (value instanceof Short)
num = new Short((short) (value.shortValue() + stepSize.shortValue()));
else
num = new Byte((byte) (value.byteValue() + stepSize.byteValue()));
return maximum.compareTo(num) >= 0 ? num : null;
}
/**
* Gets the previous value without changing the current value, or null if
* the current value is minimum.
*
* @return the previous value
*/
public Object getPreviousValue()
{
Number num;
if (value instanceof Double)
num = new Double(value.doubleValue() - stepSize.doubleValue());
else if (value instanceof Float)
num = new Double(value.floatValue() - stepSize.floatValue());
else if (value instanceof Long)
num = new Long(value.longValue() - stepSize.longValue());
else if (value instanceof Integer)
num = new Integer(value.intValue() - stepSize.intValue());
else if (value instanceof Short)
num = new Short((short) (value.shortValue() - stepSize.shortValue()));
else
num = new Byte((byte) (value.byteValue() - stepSize.byteValue()));
return minimum.compareTo(num) <= 0 ? num : null;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Number getNumber()
{
return value;
}
}

View File

@ -0,0 +1,55 @@
/* TransferHandler.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing;
import java.io.Serializable;
public class TransferHandler implements Serializable
{
private static final long serialVersionUID = -7908749299918704233L;
public static final int NONE = 0;
public static final int COPY = 1;
public static final int MOVE = 2;
public static final int COPY_OR_MOVE = 3;
protected TransferHandler()
{
// Do nothing here.
}
}

View File

@ -0,0 +1,860 @@
/* DefaultHSBChooserPanel.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.colorchooser;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.MemoryImageSource;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* This is the Default HSB Panel displayed in the JColorChooser.
*/
class DefaultHSBChooserPanel extends AbstractColorChooserPanel
{
/** The gradient image displayed. */
private transient Image gradientImage;
/** The Panel that holds the gradient image. */
private transient JPanel gradientPanel;
/** The track gradient image. */
private transient Image trackImage;
/** The panel that holds the track. */
private transient JPanel trackPanel;
/** The slider for the locked HSB value. */
private transient JSlider slider;
/** The RadioButton that controls the Hue. */
private transient JRadioButton hRadio;
/** The RadioButton that controls the Saturation. */
private transient JRadioButton sRadio;
/** The RadioButton that controls the Brightness. */
private transient JRadioButton bRadio;
/** The JSpinner that controls the Hue. */
private transient JSpinner hSpinner;
/** The JSpinner that controls the Saturation. */
private transient JSpinner sSpinner;
/** The JSpinner that controls the Brightness. */
private transient JSpinner bSpinner;
/** The default width of the gradient image. */
private static final int imgWidth = 200;
/** The default height of the gradient image. */
private static final int imgHeight = 200;
/** The default width of the track gradient. */
private static final int trackWidth = 30;
/** The JLabel for Red. */
private static final JLabel R = new JLabel("R");
/** The JLabel for Green. */
private static final JLabel G = new JLabel("G");
/** The JLabel for Blue. */
private static final JLabel B = new JLabel("B");
// FIXME: Should be textfields.
/** The JLabel that displays the value of Red. */
private transient JLabel rFull;
/** The JLabel that displays the value of Green. */
private transient JLabel gFull;
/** The JLabel that displays the value of Blue. */
private transient JLabel bFull;
/** The point that is displayed in the gradient image. */
private transient Point gradientPoint = new Point();
/**
* This indicates that the change to the slider or point is triggered
* internally.
*/
private transient boolean internalChange = false;
/** This indicates that the change to the spinner is triggered internally. */
private transient boolean spinnerTrigger = false;
/** This int identifies which spinner is currently locked. */
private transient int locked = -1;
/** This value indicates that the Hue spinner is locked. */
static final int HLOCKED = 0;
/** This value indicates that the Saturation spinner is locked. */
static final int SLOCKED = 1;
/** This value indicates that the Brightness spinner is locked. */
static final int BLOCKED = 2;
/**
* This method indicates that the mouse event is in the process of being
* handled.
*/
private transient boolean handlingMouse;
/**
* This helper class handles mouse events on the gradient image.
*/
class MainGradientMouseListener extends MouseAdapter
implements MouseMotionListener
{
/**
* This method is called when the mouse is pressed over the gradient
* image. The JColorChooser is then updated with new HSB values.
*
* @param e The MouseEvent.
*/
public void mousePressed(MouseEvent e)
{
gradientPoint = e.getPoint();
update(e.getPoint());
}
/**
* This method is called when the mouse is dragged over the gradient
* image. The JColorChooser is then updated with the new HSB values.
*
* @param e The MouseEvent.
*/
public void mouseDragged(MouseEvent e)
{
Point p = e.getPoint();
if (p.x < 0 || p.y < 0 || p.y > imgHeight || p.x > imgWidth)
return;
gradientPoint = p;
update(p);
}
/**
* This method is called when the mouse is moved over the gradient image.
*
* @param e The MouseEvent.
*/
public void mouseMoved(MouseEvent e)
{
// Do nothing.
}
/**
* This method updates the JColorChooser with the new values.
*
* @param p The Point where the MouseEvent occurred.
*/
private void update(Point p)
{
handlingMouse = true;
if (hSpinner.isEnabled())
updateH(p);
else if (sSpinner.isEnabled())
updateS(p);
else
updateB(p);
handlingMouse = false;
}
/**
* This method updates the SB values if Hue is locked.
*
* @param p The point where the MouseEvent occurred.
*/
private void updateH(Point p)
{
float s = (imgWidth - p.x * 1f) / imgWidth;
float b = (imgHeight - p.y * 1f) / imgHeight;
// Avoid two changes to the model by changing internalChange to true.
internalChange = true;
sSpinner.setValue(new Integer((int) (s * 100)));
internalChange = false;
bSpinner.setValue(new Integer((int) (b * 100)));
revalidate();
}
/**
* This method updates the HB values if Saturation is locked.
*
* @param p The point where the MouseEvent occurred.
*/
private void updateS(Point p)
{
float h = p.x * 1f / imgWidth;
float b = (imgHeight - p.y * 1f) / imgHeight;
internalChange = true;
hSpinner.setValue(new Integer((int) (h * 365)));
internalChange = false;
bSpinner.setValue(new Integer((int) (b * 100)));
revalidate();
}
/**
* This method updates the HS values if Brightness is locked.
*
* @param p The point where the MouseEvent occurred.
*/
private void updateB(Point p)
{
float h = p.x * 1f / imgWidth;
float s = (imgHeight - p.y * 1f) / imgHeight;
internalChange = true;
hSpinner.setValue(new Integer((int) (h * 365)));
internalChange = false;
sSpinner.setValue(new Integer((int) (s * 100)));
revalidate();
}
}
/**
* This method listens for slider value changes.
*/
class SliderChangeListener implements ChangeListener
{
/**
* This method is called when the slider value changes. It should change
* the color of the JColorChooser.
*
* @param e The ChangeEvent.
*/
public void stateChanged(ChangeEvent e)
{
if (internalChange)
return;
Integer value = new Integer(slider.getValue());
switch (locked)
{
case HLOCKED:
hSpinner.setValue(value);
break;
case SLOCKED:
sSpinner.setValue(value);
break;
case BLOCKED:
bSpinner.setValue(value);
break;
}
}
}
/**
* This helper class determines the active JSpinner.
*/
class RadioStateListener implements ChangeListener
{
/**
* This method is called when there is a new JRadioButton that was
* selected. As a result, it should activate the associated JSpinner.
*
* @param e The ChangeEvent.
*/
public void stateChanged(ChangeEvent e)
{
JSpinner change;
if (e.getSource() == hRadio)
{
locked = HLOCKED;
change = hSpinner;
}
else if (e.getSource() == sRadio)
{
locked = SLOCKED;
change = sSpinner;
}
else
{
locked = BLOCKED;
change = bSpinner;
}
change.setEnabled(((AbstractButton) e.getSource()).isSelected());
updateSlider();
updateTrack();
updateImage();
repaint();
}
}
/**
* This class listens to the JSpinners for changes.
*/
class ImageScrollListener implements ChangeListener
{
/**
* This method is called whenever one of the JSpinner values change. The
* JColorChooser should be updated with the new HSB values.
*
* @param e The ChangeEvent.
*/
public void stateChanged(ChangeEvent e)
{
if (internalChange)
return;
float h = ((Number) hSpinner.getValue()).intValue() / 360f;
float s = ((Number) sSpinner.getValue()).intValue() / 100f;
float b = ((Number) bSpinner.getValue()).intValue() / 100f;
spinnerTrigger = true;
getColorSelectionModel().setSelectedColor(new Color(Color.HSBtoRGB(h, s,
b)));
spinnerTrigger = false;
if (! handlingMouse)
{
updateImage();
updateTrack();
}
repaint();
}
}
/**
* Creates a new DefaultHSBChooserPanel object.
*/
DefaultHSBChooserPanel()
{
super();
}
/**
* This method returns the name displayed by the JColorChooser tab that
* holds this panel.
*
* @return The name displayed in the JColorChooser tab.
*/
public String getDisplayName()
{
return "HSB";
}
/**
* This method updates the various components inside the HSBPanel (the
* JSpinners, the JSlider, and the gradient image point) with updated
* values when the JColorChooser color value changes.
*/
public void updateChooser()
{
Color c = getColorSelectionModel().getSelectedColor();
float[] hsbVals = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(),
null);
internalChange = true;
// spinnerTrigger, internalChange, and handlingMouse are used because of the
// we don't want things like: change spinner -> update chooser -> change spinner
// That's because the value from before and after the update can differ
// slightly because of the conversion.
// FIXME: Think of better way to deal with this.
if (! spinnerTrigger)
{
hSpinner.setValue(new Integer((int) (hsbVals[0] * 360)));
sSpinner.setValue(new Integer((int) (hsbVals[1] * 100)));
bSpinner.setValue(new Integer((int) (hsbVals[2] * 100)));
}
switch (locked)
{
case HLOCKED:
if (slider != null)
slider.setValue(((Number) hSpinner.getValue()).intValue());
if (! handlingMouse)
{
gradientPoint.x = (int) ((1 - hsbVals[1]) * imgWidth);
gradientPoint.y = (int) ((1 - hsbVals[2]) * imgHeight);
}
break;
case SLOCKED:
if (slider != null)
slider.setValue(((Number) sSpinner.getValue()).intValue());
if (! handlingMouse)
{
gradientPoint.x = (int) (hsbVals[0] * imgWidth);
gradientPoint.y = (int) ((1 - hsbVals[2]) * imgHeight);
}
break;
case BLOCKED:
if (slider != null)
slider.setValue(((Number) bSpinner.getValue()).intValue());
if (! handlingMouse)
{
gradientPoint.x = (int) (hsbVals[0] * imgWidth);
gradientPoint.y = (int) ((1 - hsbVals[1]) * imgHeight);
}
break;
}
internalChange = false;
updateImage();
updateTrack();
updateTextFields();
}
/**
* This method builds the DefaultHSBChooserPanel.
*/
protected void buildChooser()
{
setLayout(new BorderLayout());
add(buildRightPanel(), BorderLayout.EAST);
JPanel container = new JPanel();
container.setLayout(new BorderLayout());
gradientPanel = new JPanel()
{
public Dimension getPreferredSize()
{
return new Dimension(imgWidth, imgHeight);
}
public void paint(Graphics g)
{
if (gradientImage != null)
g.drawImage(gradientImage, 0, 0, this);
Color saved = g.getColor();
g.setColor(Color.WHITE);
g.drawOval(gradientPoint.x - 3, gradientPoint.y - 3, 6, 6);
g.setColor(saved);
}
};
MouseAdapter ml = new MainGradientMouseListener();
gradientPanel.addMouseListener(ml);
gradientPanel.addMouseMotionListener((MouseMotionListener) ml);
trackPanel = new JPanel()
{
public Dimension getPreferredSize()
{
return new Dimension(trackWidth, imgHeight);
}
public void paint(Graphics g)
{
if (trackImage != null)
g.drawImage(trackImage, 0, 0, this);
}
};
slider = new JSlider();
slider.setPaintTrack(false);
slider.setPaintTicks(false);
slider.setOrientation(SwingConstants.VERTICAL);
updateSlider();
container.add(gradientPanel, BorderLayout.WEST);
container.add(slider, BorderLayout.CENTER);
container.add(trackPanel, BorderLayout.EAST);
add(container, BorderLayout.WEST);
slider.addChangeListener(new SliderChangeListener());
repaint();
}
/**
* This method uninstalls the DefaultHSBPanel.
*
* @param chooser The JColorChooser to remove this panel from.
*/
public void uninstallChooserPanel(JColorChooser chooser)
{
trackImage = null;
gradientImage = null;
gradientPanel = null;
slider = null;
hSpinner = null;
sSpinner = null;
bSpinner = null;
hRadio = null;
sRadio = null;
bRadio = null;
removeAll();
super.uninstallChooserPanel(chooser);
}
/**
* This helper method creates the right side panel (the panel with the
* Spinners and TextFields).
*
* @return The right side panel.
*/
private Container buildRightPanel()
{
JPanel container = new JPanel();
container.setLayout(new GridLayout(6, 2));
hRadio = new JRadioButton("H");
sRadio = new JRadioButton("S");
bRadio = new JRadioButton("B");
ButtonGroup group = new ButtonGroup();
group.add(hRadio);
group.add(sRadio);
group.add(bRadio);
hSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 359, 1));
sSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 100, 1));
bSpinner = new JSpinner(new SpinnerNumberModel(100, 0, 100, 1));
hSpinner.setEnabled(false);
sSpinner.setEnabled(false);
bSpinner.setEnabled(false);
ChangeListener cl = new RadioStateListener();
ChangeListener scroll = new ImageScrollListener();
hRadio.addChangeListener(cl);
sRadio.addChangeListener(cl);
bRadio.addChangeListener(cl);
hSpinner.addChangeListener(scroll);
sSpinner.addChangeListener(scroll);
bSpinner.addChangeListener(scroll);
hRadio.setSelected(true);
container.add(hRadio);
container.add(hSpinner);
container.add(sRadio);
container.add(sSpinner);
container.add(bRadio);
container.add(bSpinner);
rFull = new JLabel("red full");
gFull = new JLabel("green full");
bFull = new JLabel("blue full");
container.add(R);
container.add(rFull);
container.add(G);
container.add(gFull);
container.add(B);
container.add(bFull);
return container;
}
/**
* This method returns the small display icon.
*
* @return The small display icon.
*/
public Icon getSmallDisplayIcon()
{
return null;
}
/**
* This method returns the large display icon.
*
* @return The large display icon.
*/
public Icon getLargeDisplayIcon()
{
return null;
}
/**
* This method paints the chooser panel.
*
* @param g The graphics object to paint with.
*/
public void paint(Graphics g)
{
super.paint(g);
}
/**
* This method updates the gradient image with a new one taking the Hue
* value as the constant.
*/
private void updateHLockImage()
{
int index = 0;
int[] pix = new int[imgWidth * imgHeight];
float hValue = ((Number) hSpinner.getValue()).intValue() / 360f;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < imgWidth; i++)
pix[index++] = Color.HSBtoRGB(hValue, (imgWidth - i * 1f) / imgWidth,
(imgHeight - j * 1f) / imgHeight)
| (255 << 24);
gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight,
pix, 0, imgWidth));
}
/**
* This method updates the gradient image with a new one taking the
* Brightness value as the constant.
*/
private void updateBLockImage()
{
int[] pix = new int[imgWidth * imgHeight];
float bValue = ((Number) bSpinner.getValue()).intValue() / 100f;
int index = 0;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < imgWidth; i++)
pix[index++] = Color.HSBtoRGB(i * 1f / imgWidth,
(imgHeight - j * 1f) / imgHeight, bValue)
| (255 << 24);
gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight,
pix, 0, imgWidth));
}
/**
* This method updates the gradient image with a new one taking the
* Saturation value as the constant.
*/
private void updateSLockImage()
{
int[] pix = new int[imgWidth * imgHeight];
float sValue = ((Number) sSpinner.getValue()).intValue() / 100f;
int index = 0;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < imgWidth; i++)
pix[index++] = Color.HSBtoRGB(i * 1f / imgWidth, sValue,
(imgHeight - j * 1f) / imgHeight)
| (255 << 24);
gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight,
pix, 0, imgWidth));
}
/**
* This method calls the appropriate method to update the gradient image
* depending on which HSB value is constant.
*/
private void updateImage()
{
switch (locked)
{
case HLOCKED:
updateHLockImage();
break;
case SLOCKED:
updateSLockImage();
break;
case BLOCKED:
updateBLockImage();
break;
}
}
/**
* This method updates the TextFields with the correct RGB values.
*/
private void updateTextFields()
{
int c = getColorSelectionModel().getSelectedColor().getRGB();
rFull.setText("" + (c >> 16 & 0xff));
gFull.setText("" + (c >> 8 & 0xff));
bFull.setText("" + (c & 0xff));
repaint();
}
/**
* This method updates the slider in response to making a different HSB
* property the constant.
*/
private void updateSlider()
{
if (slider == null)
return;
slider.setMinimum(0);
if (locked == HLOCKED)
{
slider.setMaximum(359);
;
slider.setValue(((Number) hSpinner.getValue()).intValue());
slider.setInverted(true);
}
else
{
slider.setMaximum(100);
slider.setInverted(false);
if (sRadio.isSelected())
slider.setValue(((Number) sSpinner.getValue()).intValue());
else
slider.setValue(((Number) bSpinner.getValue()).intValue());
}
repaint();
}
/**
* This method updates the track gradient image depending on which HSB
* property is constant.
*/
private void updateTrack()
{
switch (locked)
{
case HLOCKED:
updateHTrack();
break;
case SLOCKED:
updateSTrack();
break;
case BLOCKED:
updateBTrack();
break;
}
}
/**
* This method updates the track gradient image if the Hue value is allowed
* to change (according to the JRadioButtons).
*/
private void updateHTrack()
{
int trackIndex = 0;
int[] trackPix = new int[trackWidth * imgHeight];
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < trackWidth; i++)
trackPix[trackIndex++] = Color.HSBtoRGB(j * 1f / imgHeight, 1f, 1f)
| (255 << 24);
trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight,
trackPix, 0, trackWidth));
}
/**
* This method updates the track gradient image if the Saturation value is
* allowed to change (according to the JRadioButtons).
*/
private void updateSTrack()
{
int[] trackPix = new int[trackWidth * imgHeight];
float hValue = ((Number) hSpinner.getValue()).intValue() / 360f;
float bValue = ((Number) bSpinner.getValue()).intValue() / 100f;
int trackIndex = 0;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < trackWidth; i++)
trackPix[trackIndex++] = Color.HSBtoRGB(hValue,
(imgHeight - j * 1f) / imgHeight,
bValue) | (255 << 24);
trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight,
trackPix, 0, trackWidth));
}
/**
* This method updates the track gradient image if the Brightness value is
* allowed to change (according to the JRadioButtons).
*/
private void updateBTrack()
{
int[] trackPix = new int[trackWidth * imgHeight];
float hValue = ((Number) hSpinner.getValue()).intValue() / 360f;
float sValue = ((Number) sSpinner.getValue()).intValue() / 100f;
int trackIndex = 0;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < trackWidth; i++)
trackPix[trackIndex++] = Color.HSBtoRGB(hValue, sValue,
(imgHeight - j * 1f) / imgHeight)
| (255 << 24);
trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight,
trackPix, 0, trackWidth));
}
}

View File

@ -0,0 +1,317 @@
/* DefaultPreviewPanel.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.colorchooser;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.JColorChooser;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
/**
* This is the default preview panel for the JColorChooser. The default
* preview panel is responsible for displaying the currently selected color
* of the JColorChooser.
*/
class DefaultPreviewPanel extends JPanel
{
/**
* This is the border around the preview panel.
*/
class PreviewBorder implements Border
{
/** This is the value of the top, bottom, top, and right inset. */
private static final int edge = 20;
/**
* This is the distance from the top left corner of the border to the
* text.
*/
private static final int lead = 5;
/** This is the horizontal gap between the text and the border. */
private static final int gap = 3;
/**
* This method returns the border insets for the given Component.
*
* @param c The Component to retrieve insets for.
*
* @return The insets for the given Component.
*/
public Insets getBorderInsets(Component c)
{
return new Insets(edge, edge, edge, edge);
}
/**
* This method returns whether the border is responsible for painting its
* own background.
*
* @return Whether the border is responsible for painting its own
* background.
*/
public boolean isBorderOpaque()
{
return true;
}
/**
* This method paints the border for the given component with the graphics
* object using the given properties.
*
* @param c The Component to paint the border for.
* @param g The Graphics object to paint with.
* @param x The x location to paint at.
* @param y The y location to paint at.
* @param width The width of the component.
* @param height The height of the component.
*/
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height)
{
Color saved = g.getColor();
FontMetrics fm = g.getFontMetrics();
g.setColor(Color.BLACK);
g.drawLine(x + edge / 2, y + edge / 2, x + edge / 2,
y + height - edge / 2);
g.drawLine(x + edge / 2, y + height - edge / 2, x + width - edge / 2,
y + height - edge / 2);
g.drawLine(x + width - edge / 2, y + edge / 2, x + width - edge / 2,
y + height - edge / 2);
g.drawLine(x + edge / 2, y + edge / 2, x + edge / 2 + lead, y + edge / 2);
int strwidth = fm.stringWidth("Preview");
g.drawString("Preview", x + edge / 2 + lead + gap,
y + edge / 2 + fm.getAscent() / 2);
g.drawLine(x + lead + edge / 2 + strwidth + gap * 2, y + edge / 2,
x + width - edge / 2, y + edge / 2);
g.setColor(saved);
}
}
/** A standard large gap size. */
private static int largeGap = 6;
/** A standard small gap size. */
private static int smallGap = 2;
/** The size of each side of the square. */
private static int squareSize = 36;
/** This padding between the text and the edge of its box. */
private static int textPadding = 4;
/** The width of the right most rectangles. */
private static int rightSideRectWidth = 60;
/** The sample text. */
private static String sample = "Sample Text Sample Text";
/**
* Creates a new DefaultPreviewPanel object.
*/
DefaultPreviewPanel()
{
super();
setBorder(new PreviewBorder());
}
/**
* This method paints the default preview panel with the given Graphics
* object.
*
* @param g The Graphics object.
*/
public void paint(Graphics g)
{
super.paint(g);
Color currentColor = null;
JColorChooser chooser = (JColorChooser) SwingUtilities.getAncestorOfClass(JColorChooser.class,
this);
if (chooser != null)
currentColor = chooser.getColor();
Color saved = g.getColor();
Insets insets = getInsets();
int down = insets.top + squareSize + largeGap;
int currX = insets.left;
paintSquare(g, currX, insets.top, Color.WHITE, currentColor, Color.WHITE,
-1, -1, -1);
paintSquare(g, currX, down, currentColor, null, null, -1, -1, -1);
currX += squareSize + largeGap;
paintSquare(g, currX, insets.top, Color.BLACK, currentColor, Color.WHITE,
-1, -1, -1);
paintSquare(g, currX, down, Color.WHITE, currentColor, null, -1, -1, -1);
currX += squareSize + largeGap;
paintSquare(g, currX, insets.top, Color.WHITE, currentColor, Color.BLACK,
-1, -1, -1);
paintSquare(g, currX, down, Color.BLACK, currentColor, null, -1, -1, -1);
FontMetrics fm = g.getFontMetrics();
int strWidth = fm.stringWidth(sample);
int strHeight = fm.getHeight();
currX += squareSize + largeGap;
int boxWidth = 2 * textPadding + strWidth;
int boxHeight = 2 * textPadding + strHeight;
int first = insets.top + textPadding;
int second = insets.top + boxHeight + smallGap;
int third = insets.top + 2 * (boxHeight + smallGap);
g.setColor(Color.WHITE);
g.fillRect(currX, third, boxWidth, boxHeight);
g.setColor(currentColor);
g.drawString(sample, currX + textPadding,
first + textPadding + fm.getAscent());
g.fillRect(currX, second, boxWidth, boxHeight);
g.drawString(sample, currX + textPadding,
third + textPadding + fm.getAscent());
g.setColor(Color.BLACK);
g.drawString(sample, currX + textPadding,
second + textPadding + fm.getAscent());
currX += boxWidth + largeGap;
g.setColor(Color.WHITE);
g.fillRect(currX, insets.top, rightSideRectWidth, squareSize
+ largeGap / 2);
g.setColor(currentColor);
g.fillRect(currX, insets.top + squareSize + largeGap / 2,
rightSideRectWidth, squareSize + largeGap / 2);
g.setColor(saved);
}
/**
* This method creates and paints a square. The square has two smaller
* squares inside of it. Each of the three squares has their sizes
* determined by the size arguments. If the size is not given (by passing
* in -1), then the size is determined automatically.
*
* @param g The Graphics object to paint with.
* @param x The x location to paint at.
* @param y The y location to paint at.
* @param first The color of the first square.
* @param second The color of the second square.
* @param third The color of the third square.
* @param firstSize The size of the first square.
* @param secondSize The size of the second square.
* @param thirdSize The size of the third square.
*/
private void paintSquare(Graphics g, int x, int y, Color first,
Color second, Color third, int firstSize,
int secondSize, int thirdSize)
{
Color saved = g.getColor();
if (firstSize == -1)
firstSize = squareSize;
if (secondSize == -1)
secondSize = squareSize * 2 / 3;
if (thirdSize == -1)
thirdSize = squareSize / 3;
int secondOffset = (firstSize - secondSize) / 2;
int thirdOffset = (firstSize - thirdSize) / 2;
if (first == null)
return;
g.setColor(first);
g.fillRect(x, y, firstSize, firstSize);
if (second == null)
return;
g.setColor(second);
g.fillRect(x + secondOffset, y + secondOffset, secondSize, secondSize);
if (third == null)
return;
g.setColor(third);
g.fillRect(x + thirdOffset, y + thirdOffset, thirdSize, thirdSize);
g.setColor(saved);
}
/**
* This method returns the preferred size of the default preview panel.
*
* @return The preferred size of the default preview panel.
*/
public Dimension getPreferredSize()
{
Graphics g = getGraphics();
FontMetrics fm = g.getFontMetrics();
g.dispose();
int strWidth = fm.stringWidth(sample);
int strHeight = fm.getHeight();
int h1 = (strHeight + 2 * textPadding) * 3 + 2 * smallGap;
int h2 = 2 * squareSize + largeGap;
int height = Math.max(h1, h2);
int width = 3 * (squareSize + largeGap) + strWidth + 2 * textPadding
+ largeGap + rightSideRectWidth;
Insets insets = getInsets();
return new Dimension(width + insets.right + insets.left,
height + insets.top + insets.bottom);
}
}

View File

@ -0,0 +1,377 @@
/* DefaultRGHChooserPanel.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.colorchooser;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.Icon;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* This is the default RGB panel for the JColorChooser. The color is selected
* using three sliders that represent the RGB values.
*/
public class DefaultRGBChooserPanel extends AbstractColorChooserPanel
{
/**
* This class handles the slider value changes for all three sliders.
*/
class SliderHandler implements ChangeListener
{
/**
* This method is called whenever any of the slider values change.
*
* @param e The ChangeEvent.
*/
public void stateChanged(ChangeEvent e)
{
if (internalChange)
return;
int color = R.getValue() << 16 | G.getValue() << 8 | B.getValue();
getColorSelectionModel().setSelectedColor(new Color(color));
}
}
/**
* This class handles the Spinner values changing.
*/
class SpinnerHandler implements ChangeListener
{
/**
* This method is called whenever any of the JSpinners change values.
*
* @param e The ChangeEvent.
*/
public void stateChanged(ChangeEvent e)
{
if (internalChange)
return;
int red = ((Number) RSpinner.getValue()).intValue();
int green = ((Number) GSpinner.getValue()).intValue();
int blue = ((Number) BSpinner.getValue()).intValue();
int color = red << 16 | green << 8 | blue;
getColorSelectionModel().setSelectedColor(new Color(color));
}
}
/**
* Whether the color change was initiated from the slider or spinner rather
* than externally.
*/
private transient boolean internalChange = false;
/** The ChangeListener for the sliders. */
private transient ChangeListener colorChanger;
/** The ChangeListener for the spinners. */
private transient ChangeListener spinnerHandler;
/** The slider that handles the red values. */
private transient JSlider R;
/** The slider that handles the green values. */
private transient JSlider G;
/** The slider that handles the blue values. */
private transient JSlider B;
/** The label for the red slider. */
private transient JLabel RLabel;
/** The label for the green slider. */
private transient JLabel GLabel;
/** The label for the blue slider. */
private transient JLabel BLabel;
/** The spinner that handles the red values. */
private transient JSpinner RSpinner;
/** The spinner that handles the green values. */
private transient JSpinner GSpinner;
/** The spinner that handles the blue values. */
private transient JSpinner BSpinner;
/**
* Creates a new DefaultRGBChooserPanel object.
*/
public DefaultRGBChooserPanel()
{
super();
}
/**
* This method returns the name displayed in the JTabbedPane.
*
* @return The name displayed in the JTabbedPane.
*/
public String getDisplayName()
{
return "RGB";
}
/**
* This method updates the chooser panel with the new color chosen in the
* JColorChooser.
*/
public void updateChooser()
{
Color c = getColorFromModel();
int rgb = c.getRGB();
int red = rgb >> 16 & 0xff;
int green = rgb >> 8 & 0xff;
int blue = rgb & 0xff;
internalChange = true;
if (R != null)
R.setValue(red);
if (RSpinner != null)
RSpinner.setValue(new Integer(red));
if (G != null)
G.setValue(green);
if (GSpinner != null)
GSpinner.setValue(new Integer(green));
if (B != null)
B.setValue(blue);
if (BSpinner != null)
BSpinner.setValue(new Integer(blue));
internalChange = false;
revalidate();
repaint();
}
/**
* This method builds the chooser panel.
*/
protected void buildChooser()
{
setLayout(new GridBagLayout());
RLabel = new JLabel("Red");
RLabel.setDisplayedMnemonic('d');
GLabel = new JLabel("Green");
GLabel.setDisplayedMnemonic('n');
BLabel = new JLabel("Blue");
BLabel.setDisplayedMnemonic('B');
R = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 255);
G = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 255);
B = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 255);
R.setPaintTicks(true);
R.setSnapToTicks(false);
G.setPaintTicks(true);
G.setSnapToTicks(false);
B.setPaintTicks(true);
B.setSnapToTicks(false);
R.setLabelTable(R.createStandardLabels(85));
R.setPaintLabels(true);
G.setLabelTable(G.createStandardLabels(85));
G.setPaintLabels(true);
B.setLabelTable(B.createStandardLabels(85));
B.setPaintLabels(true);
R.setMajorTickSpacing(85);
G.setMajorTickSpacing(85);
B.setMajorTickSpacing(85);
R.setMinorTickSpacing(17);
G.setMinorTickSpacing(17);
B.setMinorTickSpacing(17);
RSpinner = new JSpinner(new SpinnerNumberModel(R.getValue(),
R.getMinimum(),
R.getMaximum(), 1));
GSpinner = new JSpinner(new SpinnerNumberModel(G.getValue(),
G.getMinimum(),
G.getMaximum(), 1));
BSpinner = new JSpinner(new SpinnerNumberModel(B.getValue(),
B.getMinimum(),
B.getMaximum(), 1));
RLabel.setLabelFor(R);
GLabel.setLabelFor(G);
BLabel.setLabelFor(B);
GridBagConstraints bag = new GridBagConstraints();
bag.fill = GridBagConstraints.VERTICAL;
bag.gridx = 0;
bag.gridy = 0;
add(RLabel, bag);
bag.gridx = 1;
add(R, bag);
bag.gridx = 2;
add(RSpinner, bag);
bag.gridx = 0;
bag.gridy = 1;
add(GLabel, bag);
bag.gridx = 1;
add(G, bag);
bag.gridx = 2;
add(GSpinner, bag);
bag.gridx = 0;
bag.gridy = 2;
add(BLabel, bag);
bag.gridx = 1;
add(B, bag);
bag.gridx = 2;
add(BSpinner, bag);
installListeners();
}
/**
* This method uninstalls the chooser panel from the JColorChooser.
*
* @param chooser The JColorChooser to remove this chooser panel from.
*/
public void uninstallChooserPanel(JColorChooser chooser)
{
uninstallListeners();
removeAll();
R = null;
G = null;
B = null;
RSpinner = null;
GSpinner = null;
BSpinner = null;
super.uninstallChooserPanel(chooser);
}
/**
* This method uninstalls any listeners that were added by the chooser
* panel.
*/
private void uninstallListeners()
{
R.removeChangeListener(colorChanger);
G.removeChangeListener(colorChanger);
B.removeChangeListener(colorChanger);
colorChanger = null;
RSpinner.removeChangeListener(spinnerHandler);
GSpinner.removeChangeListener(spinnerHandler);
BSpinner.removeChangeListener(spinnerHandler);
spinnerHandler = null;
}
/**
* This method installs any listeners that the chooser panel needs to
* operate.
*/
private void installListeners()
{
colorChanger = new SliderHandler();
R.addChangeListener(colorChanger);
G.addChangeListener(colorChanger);
B.addChangeListener(colorChanger);
spinnerHandler = new SpinnerHandler();
RSpinner.addChangeListener(spinnerHandler);
GSpinner.addChangeListener(spinnerHandler);
BSpinner.addChangeListener(spinnerHandler);
}
/**
* This method returns the small display icon.
*
* @return The small display icon.
*/
public Icon getSmallDisplayIcon()
{
return null;
}
/**
* This method returns the large display icon.
*
* @return The large display icon.
*/
public Icon getLargeDisplayIcon()
{
return null;
}
/**
* This method paints the default RGB chooser panel.
*
* @param g The Graphics object to paint with.
*/
public void paint(Graphics g)
{
super.paint(g);
}
}

View File

@ -0,0 +1,891 @@
/* DefaultSwatchChooserPanel.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.colorchooser;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.Icon;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* This class is the DefaultSwatchChooserPanel. This chooser panel displays a
* set of colors that can be picked. Recently picked items will go into a
* side panel so the user can see the history of the chosen colors.
*/
class DefaultSwatchChooserPanel extends AbstractColorChooserPanel
{
/** The main panel that holds the set of choosable colors. */
MainSwatchPanel mainPalette;
/** A panel that holds the recent colors. */
RecentSwatchPanel recentPalette;
/** The mouse handlers for the panels. */
MouseListener mouseHandler;
/**
* This the base class for all swatch panels. Swatch panels are panels that
* hold a set of blocks where colors are displayed.
*/
abstract static class SwatchPanel extends JPanel
{
/** The width of each block. */
protected int cellWidth = 10;
/** The height of each block. */
protected int cellHeight = 10;
/** The gap between blocks. */
protected int gap = 1;
/** The number of rows in the swatch panel. */
protected int numRows;
/** The number of columns in the swatch panel. */
protected int numCols;
/**
* Creates a new SwatchPanel object.
*/
SwatchPanel()
{
super();
setBackground(Color.WHITE);
}
/**
* This method returns the preferred size of the swatch panel based on the
* number of rows and columns and the size of each cell.
*
* @return The preferred size of the swatch panel.
*/
public Dimension getPreferredSize()
{
int height = numRows * cellHeight + (numRows - 1) * gap;
int width = numCols * cellWidth + (numCols - 1) * gap;
Insets insets = getInsets();
return new Dimension(width + insets.left + insets.right,
height + insets.top + insets.bottom);
}
/**
* This method returns the color for the given position.
*
* @param x The x coordinate of the position.
* @param y The y coordinate of the position.
*
* @return The color at the given position.
*/
public abstract Color getColorForPosition(int x, int y);
/**
* This method initializes the colors for the swatch panel.
*/
protected abstract void initializeColors();
}
/**
* This is the main swatch panel. This panel sits in the middle and allows a
* set of colors to be picked which will move to the recent swatch panel.
*/
static class MainSwatchPanel extends SwatchPanel
{
/** The color describing (204, 255, 255) */
public static final Color C204255255 = new Color(204, 204, 255);
/** The color describing (255, 204, 204) */
public static final Color C255204204 = new Color(255, 204, 204);
/** The color describing (204, 255, 204) */
public static final Color C204255204 = new Color(204, 255, 204);
/** The color describing (204, 204, 204) */
public static final Color C204204204 = new Color(204, 204, 204);
/** The color (153, 153, 255). */
public static final Color C153153255 = new Color(153, 153, 255);
/** The color (51, 51, 255). */
public static final Color C051051255 = new Color(51, 51, 255);
/** The color (153, 0, 153). */
public static final Color C153000153 = new Color(153, 0, 153);
/** The color (0, 51, 51). */
public static final Color C000051051 = new Color(0, 51, 51);
/** The color (51, 0, 51). */
public static final Color C051000051 = new Color(51, 0, 51);
/** The color (51, 51, 0). */
public static final Color C051051000 = new Color(51, 51, 0);
/** The color (102, 102, 0). */
public static final Color C102102000 = new Color(102, 102, 0);
/** The color (153, 255, 153). */
public static final Color C153255153 = new Color(153, 255, 153);
/** The color (102, 255, 102). */
public static final Color C102255102 = new Color(102, 255, 102);
/** The color (0, 102, 102). */
public static final Color C000102102 = new Color(0, 102, 102);
/** The color (102, 0, 102). */
public static final Color C102000102 = new Color(102, 0, 102);
/** The color (0, 153, 153). */
public static final Color C000153153 = new Color(0, 153, 153);
/** The color (153, 153, 0). */
public static final Color C153153000 = new Color(153, 153, 0);
/** The color (204, 204, 0). */
public static final Color C204204000 = new Color(204, 204, 0);
/** The color (204, 0, 204). */
public static final Color C204000204 = new Color(204, 0, 204);
/** The color (0, 204, 204). */
public static final Color C000204204 = new Color(0, 204, 204);
/** The color (51, 255, 51). */
public static final Color C051255051 = new Color(51, 255, 51);
/** The color (255, 51, 51). */
public static final Color C255051051 = new Color(255, 51, 51);
/** The color (255, 102, 102). */
public static final Color C255102102 = new Color(255, 102, 102);
/** The color (102, 102, 255). */
public static final Color C102102255 = new Color(102, 102, 255);
/** The color (255, 153, 153). */
public static final Color C255153153 = new Color(255, 153, 153);
static Color[] colors =
{
// Row 1
Color.WHITE, new Color(204, 255, 255), C204255255, C204255255, C204255255,
C204255255, C204255255, C204255255, C204255255,
C204255255, C204255255, new Color(255, 204, 255),
C255204204, C255204204, C255204204, C255204204,
C255204204, C255204204, C255204204, C255204204,
C255204204, new Color(255, 255, 204), C204255204,
C204255204, C204255204, C204255204, C204255204,
C204255204, C204255204, C204255204, C204255204,
// Row 2
C204204204, new Color(153, 255, 255), new Color(153, 204, 255), C153153255,
C153153255, C153153255, C153153255, C153153255,
C153153255, C153153255, new Color(204, 153, 255),
new Color(255, 153, 255),
new Color(255, 153, 204), C255153153, C255153153,
C255153153, C255153153, C255153153, C255153153,
C255153153, new Color(255, 204, 153),
new Color(255, 255, 153),
new Color(204, 255, 153), C153255153, C153255153,
C153255153, C153255153, C153255153, C153255153,
C153255153, new Color(153, 255, 204),
// Row 3
C204204204, new Color(102, 255, 255), new Color(102, 204, 255),
new Color(102, 153, 255), C102102255, C102102255,
C102102255, C102102255, C102102255,
new Color(153, 102, 255),
new Color(204, 102, 255),
new Color(255, 102, 255),
new Color(255, 102, 204),
new Color(255, 102, 153), C255102102, C255102102,
C255102102, C255102102, C255102102,
new Color(255, 153, 102),
new Color(255, 204, 102),
new Color(255, 255, 102),
new Color(204, 255, 102),
new Color(153, 255, 102), C102255102, C102255102,
C102255102, C102255102, C102255102,
new Color(102, 255, 153),
new Color(102, 255, 204),
// Row 4
new Color(153, 153, 153), new Color(51, 255, 255), new Color(51, 204, 255),
new Color(51, 153, 255), new Color(51, 102, 255),
C051051255, C051051255, C051051255,
new Color(102, 51, 255), new Color(153, 51, 255),
new Color(204, 51, 255), new Color(255, 51, 255),
new Color(255, 51, 204), new Color(255, 51, 153),
new Color(255, 51, 102), C255051051, C255051051,
C255051051, new Color(255, 102, 51),
new Color(255, 153, 51), new Color(255, 204, 51),
new Color(255, 255, 51), new Color(204, 255, 51),
new Color(153, 255, 51), new Color(102, 255, 51),
C051255051, C051255051, C051255051,
new Color(51, 255, 102), new Color(51, 255, 153),
new Color(51, 255, 204),
// Row 5
new Color(153, 153, 153), new Color(0, 255, 255), new Color(0, 204, 255),
new Color(0, 153, 255), new Color(0, 102, 255),
new Color(0, 51, 255), new Color(0, 0, 255),
new Color(51, 0, 255), new Color(102, 0, 255),
new Color(153, 0, 255), new Color(204, 0, 255),
new Color(255, 0, 255), new Color(255, 0, 204),
new Color(255, 0, 153), new Color(255, 0, 102),
new Color(255, 0, 51), new Color(255, 0, 0),
new Color(255, 51, 0), new Color(255, 102, 0),
new Color(255, 153, 0), new Color(255, 204, 0),
new Color(255, 255, 0), new Color(204, 255, 0),
new Color(153, 255, 0), new Color(102, 255, 0),
new Color(51, 255, 0), new Color(0, 255, 0),
new Color(0, 255, 51), new Color(0, 255, 102),
new Color(0, 255, 153), new Color(0, 255, 204),
// Row 6
new Color(102, 102, 102), C000204204, C000204204, new Color(0, 153, 204),
new Color(0, 102, 204), new Color(0, 51, 204),
new Color(0, 0, 204), new Color(51, 0, 204),
new Color(102, 0, 204), new Color(153, 0, 204),
C204000204, C204000204, C204000204,
new Color(204, 0, 153), new Color(204, 0, 102),
new Color(204, 0, 51), new Color(204, 0, 0),
new Color(204, 51, 0), new Color(204, 102, 0),
new Color(204, 153, 0), C204204000, C204204000,
C204204000, new Color(153, 204, 0),
new Color(102, 204, 0), new Color(51, 204, 0),
new Color(0, 204, 0), new Color(0, 204, 51),
new Color(0, 204, 102), new Color(0, 204, 153),
new Color(0, 204, 204),
// Row 7
new Color(102, 102, 102), C000153153, C000153153, C000153153,
new Color(0, 102, 153), new Color(0, 51, 153),
new Color(0, 0, 153), new Color(51, 0, 153),
new Color(102, 0, 153), C153000153, C153000153,
C153000153, C153000153, C153000153,
new Color(153, 0, 102), new Color(153, 0, 51),
new Color(153, 0, 0), new Color(153, 51, 0),
new Color(153, 102, 0), C153153000, C153153000,
C153153000, C153153000, C153153000,
new Color(102, 153, 0), new Color(51, 153, 0),
new Color(0, 153, 0), new Color(0, 153, 51),
new Color(0, 153, 102), C000153153, C000153153,
// Row 8
new Color(51, 51, 51), C000102102, C000102102, C000102102, C000102102,
new Color(0, 51, 102), new Color(0, 0, 102),
new Color(51, 0, 102), C102000102, C102000102,
C102000102, C102000102, C102000102, C102000102,
C102000102, new Color(102, 0, 51),
new Color(102, 0, 0), new Color(102, 51, 0),
C102102000, C102102000, C102102000, C102102000,
C102102000, C102102000, C102102000,
new Color(51, 102, 0), new Color(0, 102, 0),
new Color(0, 102, 51), C000102102, C000102102,
C000102102,
// Row 9.
Color.BLACK, C000051051, C000051051, C000051051, C000051051, C000051051,
new Color(0, 0, 51), C051000051, C051000051,
C051000051, C051000051, C051000051, C051000051,
C051000051, C051000051, C051000051,
new Color(51, 0, 0), C051051000, C051051000,
C051051000, C051051000, C051051000, C051051000,
C051051000, C051051000, new Color(0, 51, 0),
C000051051, C000051051, C000051051, C000051051,
new Color(51, 51, 51)
};
/**
* Creates a new MainSwatchPanel object.
*/
MainSwatchPanel()
{
super();
numCols = 31;
numRows = 9;
initializeColors();
revalidate();
}
/**
* This method returns the color for the given position.
*
* @param x The x location for the position.
* @param y The y location for the position.
*
* @return The color for the given position.
*/
public Color getColorForPosition(int x, int y)
{
if (x % (cellWidth + gap) > cellWidth
|| y % (cellHeight + gap) > cellHeight)
// position is located in gap.
return null;
int row = y / (cellHeight + gap);
int col = x / (cellWidth + gap);
return colors[row * numCols + col];
}
/**
* This method initializes the colors for the main swatch panel.
*/
protected void initializeColors()
{
// Unnecessary
}
/**
* This method paints the main graphics panel with the given Graphics
* object.
*
* @param graphics The Graphics object to paint with.
*/
public void paint(Graphics graphics)
{
int index = 0;
Insets insets = getInsets();
int currX = insets.left;
int currY = insets.top;
Color saved = graphics.getColor();
for (int i = 0; i < numRows; i++)
{
for (int j = 0; j < numCols; j++)
{
graphics.setColor(colors[index++]);
graphics.fill3DRect(currX, currY, cellWidth, cellHeight, true);
currX += gap + cellWidth;
}
currX = insets.left;
currY += gap + cellHeight;
}
graphics.setColor(saved);
}
/**
* This method returns the tooltip text for the given MouseEvent.
*
* @param e The MouseEvent to find tooltip text for.
*
* @return The tooltip text.
*/
public String getToolTipText(MouseEvent e)
{
Color c = getColorForPosition(e.getX(), e.getY());
if (c == null)
return null;
return (c.getRed() + "," + c.getGreen() + "," + c.getBlue());
}
}
/**
* This class is the recent swatch panel. It holds recently selected colors.
*/
public static class RecentSwatchPanel extends SwatchPanel
{
/** The array for storing recently stored colors. */
Color[] colors;
/** The default color. */
public static final Color defaultColor = Color.GRAY;
/** The index of the array that is the start. */
int start = 0;
/**
* Creates a new RecentSwatchPanel object.
*/
RecentSwatchPanel()
{
super();
numCols = 5;
numRows = 7;
initializeColors();
revalidate();
}
/**
* This method returns the color for the given position.
*
* @param x The x coordinate of the position.
* @param y The y coordinate of the position.
*
* @return The color for the given position.
*/
public Color getColorForPosition(int x, int y)
{
if (x % (cellWidth + gap) > cellWidth
|| y % (cellHeight + gap) > cellHeight)
// position is located in gap.
return null;
int row = y / (cellHeight + gap);
int col = x / (cellWidth + gap);
return colors[getIndexForCell(row, col)];
}
/**
* This method initializes the colors for the recent swatch panel.
*/
protected void initializeColors()
{
colors = new Color[numRows * numCols];
for (int i = 0; i < colors.length; i++)
colors[i] = defaultColor;
}
/**
* This method returns the array index for the given row and column.
*
* @param row The row.
* @param col The column.
*
* @return The array index for the given row and column.
*/
private int getIndexForCell(int row, int col)
{
return ((row * numCols) + col + start) % (numRows * numCols);
}
/**
* This method adds the given color to the beginning of the swatch panel.
*
* @param c The color to add.
*/
private void addColorToQueue(Color c)
{
if (--start == -1)
start = numRows * numCols - 1;
colors[start] = c;
}
/**
* This method paints the panel with the given Graphics object.
*
* @param g The Graphics object to paint with.
*/
public void paint(Graphics g)
{
Color saved = g.getColor();
Insets insets = getInsets();
int currX = insets.left;
int currY = insets.top;
for (int i = 0; i < numRows; i++)
{
for (int j = 0; j < numCols; j++)
{
g.setColor(colors[getIndexForCell(i, j)]);
g.fill3DRect(currX, currY, cellWidth, cellHeight, true);
currX += cellWidth + gap;
}
currX = insets.left;
currY += cellWidth + gap;
}
}
/**
* This method returns the tooltip text for the given MouseEvent.
*
* @param e The MouseEvent.
*
* @return The tooltip text.
*/
public String getToolTipText(MouseEvent e)
{
Color c = getColorForPosition(e.getX(), e.getY());
if (c == null)
return null;
return c.getRed() + "," + c.getGreen() + "," + c.getBlue();
}
}
/**
* This class handles mouse events for the two swatch panels.
*/
class MouseHandler extends MouseAdapter
{
/**
* This method is called whenever the mouse is pressed.
*
* @param e The MouseEvent.
*/
public void mousePressed(MouseEvent e)
{
SwatchPanel panel = (SwatchPanel) e.getSource();
Color c = panel.getColorForPosition(e.getX(), e.getY());
recentPalette.addColorToQueue(c);
DefaultSwatchChooserPanel.this.getColorSelectionModel().setSelectedColor(c);
DefaultSwatchChooserPanel.this.repaint();
}
}
/**
* This is the layout manager for the main panel.
*/
static class MainPanelLayout implements LayoutManager
{
/**
* This method is called when a new component is added to the container.
*
* @param name The name of the component.
* @param comp The added component.
*/
public void addLayoutComponent(String name, Component comp)
{
}
/**
* This method is called to set the size and position of the child
* components for the given container.
*
* @param parent The container to lay out.
*/
public void layoutContainer(Container parent)
{
Component[] comps = parent.getComponents();
Insets insets = parent.getInsets();
Dimension[] pref = new Dimension[comps.length];
int xpos = 0;
int ypos = 0;
int maxHeight = 0;
int totalWidth = 0;
for (int i = 0; i < comps.length; i++)
{
pref[i] = comps[i].getPreferredSize();
if (pref[i] == null)
return;
maxHeight = Math.max(maxHeight, pref[i].height);
totalWidth += pref[i].width;
}
ypos = (parent.getSize().height - maxHeight) / 2 + insets.top;
xpos = insets.left + (parent.getSize().width - totalWidth) / 2;
for (int i = 0; i < comps.length; i++)
{
if (pref[i] == null)
continue;
comps[i].setBounds(xpos, ypos, pref[i].width, pref[i].height);
xpos += pref[i].width;
}
}
/**
* This method is called when a component is removed from the container.
*
* @param comp The component that was removed.
*/
public void removeLayoutComponent(Component comp)
{
}
/**
* This methods calculates the minimum layout size for the container.
*
* @param parent The container.
*
* @return The minimum layout size.
*/
public Dimension minimumLayoutSize(Container parent)
{
return preferredLayoutSize(parent);
}
/**
* This method returns the preferred layout size for the given container.
*
* @param parent The container.
*
* @return The preferred layout size.
*/
public Dimension preferredLayoutSize(Container parent)
{
int xmax = 0;
int ymax = 0;
Component[] comps = parent.getComponents();
Dimension pref;
for (int i = 0; i < comps.length; i++)
{
pref = comps[i].getPreferredSize();
if (pref == null)
continue;
xmax += pref.width;
ymax = Math.max(ymax, pref.height);
}
Insets insets = parent.getInsets();
return new Dimension(insets.left + insets.right + xmax,
insets.top + insets.bottom + ymax);
}
}
/**
* This is the layout manager for the recent swatch panel.
*/
static class RecentPanelLayout implements LayoutManager
{
/**
* This method is called when a component is added to the container.
*
* @param name The name of the component.
* @param comp The added component.
*/
public void addLayoutComponent(String name, Component comp)
{
// Nothing needs to be done.
}
/**
* This method sets the size and position of the child components of the
* given container.
*
* @param parent The container to lay out.
*/
public void layoutContainer(Container parent)
{
Component[] comps = parent.getComponents();
Dimension parentSize = parent.getSize();
Insets insets = parent.getInsets();
int currY = insets.top;
Dimension pref;
for (int i = 0; i < comps.length; i++)
{
pref = comps[i].getPreferredSize();
if (pref == null)
continue;
comps[i].setBounds(insets.left, currY, pref.width, pref.height);
currY += pref.height;
}
}
/**
* This method calculates the minimum layout size for the given container.
*
* @param parent The container.
*
* @return The minimum layout size.
*/
public Dimension minimumLayoutSize(Container parent)
{
return preferredLayoutSize(parent);
}
/**
* This method calculates the preferred layout size for the given
* container.
*
* @param parent The container.
*
* @return The preferred layout size.
*/
public Dimension preferredLayoutSize(Container parent)
{
int width = 0;
int height = 0;
Insets insets = parent.getInsets();
Component[] comps = parent.getComponents();
Dimension pref;
for (int i = 0; i < comps.length; i++)
{
pref = comps[i].getPreferredSize();
if (pref != null)
{
width = Math.max(width, pref.width);
height += pref.height;
}
}
return new Dimension(width + insets.left + insets.right,
height + insets.top + insets.bottom);
}
/**
* This method is called whenever a component is removed from the
* container.
*
* @param comp The removed component.
*/
public void removeLayoutComponent(Component comp)
{
// Nothing needs to be done.
}
}
/**
* Creates a new DefaultSwatchChooserPanel object.
*/
DefaultSwatchChooserPanel()
{
super();
}
/**
* This method updates the chooser panel with the new value from the
* JColorChooser.
*/
public void updateChooser()
{
}
/**
* This method builds the chooser panel.
*/
protected void buildChooser()
{
// The structure of the swatch panel is:
// One large panel (minus the insets).
// Inside that panel, there are two panels, one holds the palette.
// The other holds the label and the recent colors palette.
// The two palettes are two custom swatch panels.
setLayout(new MainPanelLayout());
JPanel mainPaletteHolder = new JPanel();
JPanel recentPaletteHolder = new JPanel();
mainPalette = new MainSwatchPanel();
recentPalette = new RecentSwatchPanel();
JLabel label = new JLabel("Recent:");
mouseHandler = new MouseHandler();
mainPalette.addMouseListener(mouseHandler);
recentPalette.addMouseListener(mouseHandler);
mainPaletteHolder.setLayout(new BorderLayout());
mainPaletteHolder.add(mainPalette, BorderLayout.CENTER);
recentPaletteHolder.setLayout(new RecentPanelLayout());
recentPaletteHolder.add(label);
recentPaletteHolder.add(recentPalette);
JPanel main = new JPanel();
main.add(mainPaletteHolder);
main.add(recentPaletteHolder);
this.add(main);
}
/**
* This method removes the chooser panel from the JColorChooser.
*
* @param chooser The JColorChooser this panel is being removed from.
*/
public void uninstallChooserPanel(JColorChooser chooser)
{
recentPalette = null;
mainPalette = null;
removeAll();
super.uninstallChooserPanel(chooser);
}
/**
* This method returns the JTabbedPane displayed name.
*
* @return The name displayed in the JTabbedPane.
*/
public String getDisplayName()
{
return "Swatches";
}
/**
* This method returns the small display icon.
*
* @return The small display icon.
*/
public Icon getSmallDisplayIcon()
{
return null;
}
/**
* This method returns the large display icon.
*
* @return The large display icon.
*/
public Icon getLargeDisplayIcon()
{
return null;
}
/**
* This method paints the chooser panel with the given Graphics object.
*
* @param g The Graphics object to paint with.
*/
public void paint(Graphics g)
{
super.paint(g);
}
/**
* This method returns the tooltip text for the given MouseEvent.
*
* @param e The MouseEvent.
*
* @return The tooltip text.
*/
public String getToolTipText(MouseEvent e)
{
return null;
}
}

View File

@ -0,0 +1,338 @@
/* BasicColorChooserUI.java
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.colorchooser.AbstractColorChooserPanel;
import javax.swing.colorchooser.ColorChooserComponentFactory;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ColorChooserUI;
import javax.swing.plaf.ComponentUI;
/**
* This is the UI Class for the JColorChooser in the Basic Look and Feel.
*/
public class BasicColorChooserUI extends ColorChooserUI
{
/**
* This helper class handles property changes from the JColorChooser.
*/
public class PropertyHandler implements PropertyChangeListener
{
/**
* This method is called when any of the properties of the JColorChooser
* change.
*
* @param e The PropertyChangeEvent.
*/
public void propertyChange(PropertyChangeEvent e)
{
if (e.getPropertyName() == JColorChooser.CHOOSER_PANELS_PROPERTY)
makeTabs(chooser.getChooserPanels());
else if (e.getPropertyName() == JColorChooser.PREVIEW_PANEL_PROPERTY)
updatePreviewPanel(chooser.getPreviewPanel());
else if (e.getPropertyName() == JColorChooser.SELECTION_MODEL_PROPERTY)
((AbstractColorChooserPanel) pane.getSelectedComponent())
.updateChooser();
chooser.repaint();
}
}
/**
* This is a helper class that listens to the Model of the JColorChooser for
* color change events so it can update the preview panel.
*/
private class PreviewListener implements ChangeListener
{
/**
* This method is called whenever the JColorChooser's color changes.
*
* @param e The ChangeEvent.
*/
public void stateChanged(ChangeEvent e)
{
if (pane != null)
{
AbstractColorChooserPanel panel = (AbstractColorChooserPanel) pane
.getSelectedComponent();
if (panel != null)
panel.updateChooser();
}
chooser.repaint();
}
}
/**
* This helper class listens to the JTabbedPane that is used for tab
* changes.
*/
private class TabPaneListener implements ChangeListener
{
/**
* This method is called whenever a different tab is selected in the
* JTabbedPane.
*
* @param e The ChangeEvent.
*/
public void stateChanged(ChangeEvent e)
{
// Need to do this because we don't update all the tabs when they're not
// visible, so they are not informed of new colors when they're hidden.
AbstractColorChooserPanel comp = (AbstractColorChooserPanel) pane
.getSelectedComponent();
comp.updateChooser();
}
}
/** An array of default choosers to use in the JColorChooser. */
protected AbstractColorChooserPanel[] defaultChoosers;
/** The listener for the preview panel. */
protected ChangeListener previewListener;
/** The PropertyChangeListener for the JColorChooser. */
protected PropertyChangeListener propertyChangeListener;
/** The JColorChooser. */
private JColorChooser chooser;
/** The JTabbedPane that is used. */
private JTabbedPane pane;
/** The Container that holds the preview panel. */
private Container prevContainer;
/**
* Creates a new BasicColorChooserUI object.
*/
public BasicColorChooserUI()
{
super();
}
/**
* This method creates a new UI Component for the given JComponent.
*
* @param c The JComponent to create an UI for.
*
* @return A new BasicColorChooserUI.
*/
public static ComponentUI createUI(JComponent c)
{
return new BasicColorChooserUI();
}
/**
* This method creates the default chooser panels for the JColorChooser.
*
* @return The default chooser panels.
*/
protected AbstractColorChooserPanel[] createDefaultChoosers()
{
return ColorChooserComponentFactory.getDefaultChooserPanels();
}
/**
* This method installs the UI Component for the given JComponent.
*
* @param c The JComponent to install this UI for.
*/
public void installUI(JComponent c)
{
if (c instanceof JColorChooser)
{
chooser = (JColorChooser) c;
chooser.setLayout(new BorderLayout());
// Do this first, so we avoid doing work for property change events.
defaultChoosers = createDefaultChoosers();
chooser.setChooserPanels(defaultChoosers);
pane = new JTabbedPane();
pane.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
pane.repaint();
}
});
makeTabs(defaultChoosers);
chooser.add(pane, BorderLayout.NORTH);
installPreviewPanel();
installDefaults();
installListeners();
}
}
/**
* This method adds tabs to the JTabbedPane for the chooserPanels defined in
* the JColorChooser.
*
* @param panels The Panels that need tabs to be made for them.
*/
private void makeTabs(AbstractColorChooserPanel[] panels)
{
pane.removeAll();
for (int i = 0; i < panels.length; i++)
pane.addTab(panels[i].getDisplayName(), panels[i].getSmallDisplayIcon(),
panels[i]);
}
/**
* This method uninstalls this UI for the given JComponent.
*
* @param c The JComponent that will have this UI removed.
*/
public void uninstallUI(JComponent c)
{
uninstallListeners();
uninstallDefaults();
pane = null;
chooser = null;
}
/**
* This method installs the preview panel for the JColorChooser.
*/
protected void installPreviewPanel()
{
updatePreviewPanel(ColorChooserComponentFactory.getPreviewPanel());
}
/**
* This is a helper method that swaps the existing preview panel with the
* given panel.
*
* @param preview The new preview panel.
*/
private void updatePreviewPanel(JComponent preview)
{
if (prevContainer == null)
{
prevContainer = new JPanel();
prevContainer.setLayout(new BorderLayout());
chooser.add(prevContainer, BorderLayout.CENTER);
}
prevContainer.removeAll();
prevContainer.add(preview, BorderLayout.CENTER);
}
/**
* This method installs the default properties given by the Basic Look and
* Feel.
*/
protected void installDefaults()
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
chooser.setFont(defaults.getFont("ColorChooser.font"));
chooser.setForeground(defaults.getColor("ColorChooser.foreground"));
chooser.setBackground(defaults.getColor("ColorChooser.background"));
}
/**
* This method uninstalls the default properties given by the Basic Look and
* Feel.
*/
protected void uninstallDefaults()
{
chooser.setBackground(null);
chooser.setForeground(null);
chooser.setFont(null);
}
/**
* This method installs any listeners required for this UI to function.
*/
protected void installListeners()
{
propertyChangeListener = createPropertyChangeListener();
previewListener = new PreviewListener();
chooser.addPropertyChangeListener(propertyChangeListener);
chooser.getSelectionModel().addChangeListener(previewListener);
pane.addChangeListener(new TabPaneListener());
}
/**
* This method creates the PropertyChangeListener used for listening to the
* JColorChooser.
*
* @return A PropertyChangeListener.
*/
protected PropertyChangeListener createPropertyChangeListener()
{
return new PropertyHandler();
}
/**
* This method uninstalls any listeners that were previously installed by
* the UI.
*/
protected void uninstallListeners()
{
chooser.removePropertyChangeListener(propertyChangeListener);
chooser.getSelectionModel().removeChangeListener(previewListener);
previewListener = null;
propertyChangeListener = null;
}
}

View File

@ -0,0 +1,170 @@
/* BasicComboBoxEditor.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Component;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.ComboBoxEditor;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.UIResource;
/**
* This is a component that is responsible for displaying/editting selected
* item in comboBox. By default, the JTextField is returned as
* BasicComboBoxEditor.
*
* @author Olga Rodimina
*/
public class BasicComboBoxEditor extends Object implements ComboBoxEditor,
FocusListener
{
protected JTextField editor;
/**
* Creates a new BasicComboBoxEditor object.
*/
public BasicComboBoxEditor()
{
editor = new JTextField();
editor.setBorder(new EmptyBorder(1, 1, 1, 1));
}
/**
* This method returns textfield that will be used by the combo box to
* display/edit currently selected item in the combo box.
*
* @return textfield that will be used by the combo box to display/edit
* currently selected item
*/
public Component getEditorComponent()
{
return editor;
}
/**
* Sets item that should be editted when any editting operation is performed
* by the user. The value is always equal to the currently selected value
* in the combo box. Thus whenever a different value is selected from the
* combo box list then this method should be called to change editting
* item to the new selected item.
*
* @param selectedItem item that is currently selected in the combo box
*/
public void setItem(Object item)
{
editor.setText(item.toString());
}
/**
* This method returns item that is currently editable.
*
* @return item in the combo box that is currently editable
*/
public Object getItem()
{
return editor.getText();
}
public void selectAll()
{
editor.selectAll();
}
/**
* This method is called when textfield gains focus. This will enable
* editing of the selected item.
*
* @param e the FocusEvent describing change in focus.
*/
public void focusGained(FocusEvent e)
{
// FIXME: Need to implement
}
/**
* This method is called when textfield loses focus. If during this time any
* editting operation was performed by the user, then it will be cancelled
* and selected item will not be changed.
*
* @param e the FocusEvent describing change in focus
*/
public void focusLost(FocusEvent e)
{
// FIXME: Need to implement
}
/**
* This method adds actionListener to the editor. If the user will edit
* currently selected item in the textfield and pressEnter, then action
* will be performed. The actionPerformed of this ActionListener should
* change the selected item of the comboBox to the newly editted selected
* item.
*
* @param l the ActionListener responsible for changing selected item of the
* combo box when it is editted by the user.
*/
public void addActionListener(ActionListener l)
{
// FIXME: Need to implement
}
/**
* This method removes actionListener from the textfield.
*
* @param l the ActionListener to remove from the textfield.
*/
public void removeActionListener(ActionListener l)
{
// FIXME: Need to implement
}
public static class UIResource extends BasicComboBoxEditor
implements javax.swing.plaf.UIResource
{
/**
* Creates a new UIResource object.
*/
public UIResource()
{
}
}
}

View File

@ -0,0 +1,143 @@
/* BasicComboBoxRenderer.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.io.Serializable;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.SwingConstants;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.UIResource;
/**
* This class is renderer for the combo box.
*
* @author Olga Rodimina
*/
public class BasicComboBoxRenderer extends JLabel implements ListCellRenderer,
Serializable
{
/**
* This border is used whenever renderer doesn't have a focus.
*/
protected static Border noFocusBorder = new EmptyBorder(0, 0, 0, 0);
/**
* Creates a new BasicComboBoxRenderer object.
*/
public BasicComboBoxRenderer()
{
setHorizontalAlignment(SwingConstants.LEFT);
}
/**
* Returns preferredSize of the renderer
*
* @return preferredSize of the renderer
*/
public Dimension getPreferredSize()
{
return super.getPreferredSize();
}
/**
* getListCellRendererComponent
*
* @param list List of items for which to the background and foreground
* colors
* @param value object that should be rendered in the cell
* @param index index of the cell in the list of items.
* @param isSelected draw cell highlighted if isSelected is true
* @param cellHasFocus draw focus rectangle around cell if the cell has
* focus
*
* @return Component that will be used to draw the desired cell.
*/
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected,
boolean cellHasFocus)
{
String s = value.toString();
setText(s);
setOpaque(true);
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
if (isSelected)
{
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
}
else
{
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setEnabled(list.isEnabled());
setFont(list.getFont());
// Use focusCellHighlightBorder when renderer has focus and
// noFocusBorder otherwise
if (cellHasFocus)
setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
else
setBorder(noFocusBorder);
return this;
}
public static class UIResource extends BasicComboBoxRenderer
implements javax.swing.plaf.UIResource
{
/**
* Creates a new UIResource object.
*/
public UIResource()
{
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,933 @@
/* BasicComboPopup.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
/**
* UI Delegate for ComboPopup
*
* @author Olga Rodimina
*/
public class BasicComboPopup extends JPopupMenu implements ComboPopup
{
protected Timer autoscrollTimer;
/**
* ComboBox associated with this popup
*/
protected JComboBox comboBox;
/*
* FIXME: Document fields below
*/
protected boolean hasEntered;
protected boolean isAutoScrolling;
/**
* ItemListener listening to the selection changes in the combo box
*/
protected ItemListener itemListener;
/**
* This listener is not used
*/
protected KeyListener keyListener;
/**
* JList which is used to display item is the combo box
*/
protected JList list;
/**
* This listener is not used
*/
protected ListDataListener listDataListener;
/**
* MouseListener listening to mouse events occuring in the combo box's
* list.
*/
protected MouseListener listMouseListener;
/**
* MouseMotionListener listening to mouse motion events occuring in the
* combo box's list
*/
protected MouseMotionListener listMouseMotionListener;
/**
* This listener is not used
*/
protected ListSelectionListener listSelectionListener;
/**
* MouseListener listening to mouse events occuring in the combo box
*/
protected MouseListener mouseListener;
/**
* MouseMotionListener listening to mouse motion events occuring in the
* combo box
*/
protected MouseMotionListener mouseMotionListener;
/**
* PropertyChangeListener listening to changes occuring in the bound
* properties of the combo box
*/
protected PropertyChangeListener propertyChangeListener;
/*
* FIXME: Document fields below
*/
protected static int SCROLL_DOWN = 1;
protected static int SCROLL_UP = 0;
protected int scrollDirection;
/**
* JScrollPane that contains list portion of the combo box
*/
protected JScrollPane scroller;
/**
* This field is not used
*/
protected boolean valueIsAdjusting;
/**
* Creates a new BasicComboPopup object.
*
* @param comboBox the combo box with which this popup should be associated
*/
public BasicComboPopup(JComboBox comboBox)
{
this.comboBox = comboBox;
installComboBoxListeners();
// initialize list that will be used to display elements of the combo box
this.list = createList();
((JLabel) list.getCellRenderer()).setHorizontalAlignment(SwingConstants.LEFT);
configureList();
// initialize scroller. Add list to the scroller.
scroller = createScroller();
configureScroller();
// add scroller with list inside of it to JPopupMenu
super.add(scroller);
setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());
}
/**
* This method displays drow down list of combo box items on the screen.
*/
public void show()
{
Rectangle cbBounds = comboBox.getBounds();
// popup should have same width as the comboBox and should be hight anough
// to display number of rows equal to 'maximumRowCount' property
int popupHeight = getPopupHeightForRowCount(comboBox.getMaximumRowCount())
+ 4;
super.setPopupSize(cbBounds.width, popupHeight);
// location specified is relative to comboBox
super.show(comboBox, 0, cbBounds.height);
}
/**
* This method hides drop down list of items
*/
public void hide()
{
super.setVisible(false);
}
/**
* Return list cointaining JComboBox's items
*
* @return list cointaining JComboBox's items
*/
public JList getList()
{
return list;
}
/**
* Returns MouseListener that is listening to mouse events occuring in the
* combo box.
*
* @return MouseListener
*/
public MouseListener getMouseListener()
{
return mouseListener;
}
/**
* Returns MouseMotionListener that is listening to mouse motion events
* occuring in the combo box.
*
* @return MouseMotionListener
*/
public MouseMotionListener getMouseMotionListener()
{
return mouseMotionListener;
}
/**
* Returns KeyListener listening to key events occuring in the combo box.
* This method returns null because KeyHandler is not longer used.
*
* @return KeyListener
*/
public KeyListener getKeyListener()
{
return keyListener;
}
/**
* This method uninstalls the UI for the given JComponent.
*/
public void uninstallingUI()
{
uninstallComboBoxModelListeners(comboBox.getModel());
uninstallListeners();
uninstallKeyboardActions();
}
/**
* This method uninstalls listeners that were listening to changes occuring
* in the comb box's data model
*
* @param model data model for the combo box from which to uninstall
* listeners
*/
protected void uninstallComboBoxModelListeners(ComboBoxModel model)
{
model.removeListDataListener(listDataListener);
}
/**
* This method uninstalls keyboard actions installed by the UI.
*/
protected void uninstallKeyboardActions()
{
// FIXME: Need to implement
}
/**
* This method fires PopupMenuEvent indicating that combo box's popup list
* of items will become visible
*/
protected void firePopupMenuWillBecomeVisible()
{
// FIXME: Need to implement
}
/**
* This method fires PopupMenuEvent indicating that combo box's popup list
* of items will become invisible.
*/
protected void firePopupMenuWillBecomeInvisible()
{
// FIXME: Need to implement
}
/**
* This method fires PopupMenuEvent indicating that combo box's popup list
* of items was closed without selection.
*/
protected void firePopupMenuCanceled()
{
// FIXME: Need to implement
}
/**
* Creates MouseListener to listen to mouse events occuring in the combo
* box. Note that this listener doesn't listen to mouse events occuring in
* the popup portion of the combo box, it only listens to main combo box
* part.
*
* @return new MouseMotionListener that listens to mouse events occuring in
* the combo box
*/
protected MouseListener createMouseListener()
{
return new InvocationMouseHandler();
}
/**
* Create Mouse listener that listens to mouse dragging events occuring in
* the combo box. This listener is responsible for changing the selection
* in the combo box list to the component over which mouse is being
* currently dragged
*
* @return new MouseMotionListener that listens to mouse dragging events
* occuring in the combo box
*/
protected MouseMotionListener createMouseMotionListener()
{
return new InvocationMouseMotionHandler();
}
/**
* KeyListener created in this method is not used anymore.
*
* @return KeyListener that does nothing
*/
protected KeyListener createKeyListener()
{
return new InvocationKeyHandler();
}
/**
* ListSelectionListener created in this method is not used anymore
*
* @return ListSelectionListener that does nothing
*/
protected ListSelectionListener createListSelectionListener()
{
return new ListSelectionHandler();
}
/**
* Creates ListDataListener. This method returns null, because
* ListDataHandler class is obsolete and is no longer used.
*
* @return null
*/
protected ListDataListener createListDataListener()
{
return null;
}
/**
* This method creates ListMouseListener to listen to mouse events occuring
* in the combo box's item list.
*
* @return MouseListener to listen to mouse events occuring in the combo
* box's items list.
*/
protected MouseListener createListMouseListener()
{
return new ListMouseHandler();
}
/**
* Creates ListMouseMotionlistener to listen to mouse motion events occuring
* in the combo box's list. This listener is responsible for highlighting
* items in the list when mouse is moved over them.
*
* @return MouseMotionListener that handles mouse motion events occuring in
* the list of the combo box.
*/
protected MouseMotionListener createListMouseMotionListener()
{
return new ListMouseMotionHandler();
}
/**
* Creates PropertyChangeListener to handle changes in the JComboBox's bound
* properties.
*
* @return PropertyChangeListener to handle changes in the JComboBox's bound
* properties.
*/
protected PropertyChangeListener createPropertyChangeListener()
{
return new PropertyChangeHandler();
}
/**
* Creates new ItemListener that will listen to ItemEvents occuring in the
* combo box.
*
* @return ItemListener to listen to ItemEvents occuring in the combo box.
*/
protected ItemListener createItemListener()
{
return new ItemHandler();
}
/**
* Creates JList that will be used to display items in the combo box.
*
* @return JList that will be used to display items in the combo box.
*/
protected JList createList()
{
JList l = new JList(comboBox.getModel());
l.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
return l;
}
/**
* This method configures the list of comboBox's items by setting default
* properties and installing listeners.
*/
protected void configureList()
{
list.setModel(comboBox.getModel());
if (comboBox.getItemCount() < comboBox.getMaximumRowCount())
list.setVisibleRowCount(comboBox.getItemCount());
else
list.setVisibleRowCount(comboBox.getMaximumRowCount());
installListListeners();
}
/**
* This method installs list listeners.
*/
protected void installListListeners()
{
// mouse listener listening to mouse events occuring in the
// combo box's list of items.
listMouseListener = createListMouseListener();
list.addMouseListener(listMouseListener);
// mouse listener listening to mouse motion events occuring in the
// combo box's list of items
listMouseMotionListener = createListMouseMotionListener();
list.addMouseMotionListener(listMouseMotionListener);
listSelectionListener = createListSelectionListener();
list.addListSelectionListener(listSelectionListener);
}
/**
* This method creates scroll pane that will contain the list of comboBox's
* items inside of it.
*
* @return JScrollPane
*/
protected JScrollPane createScroller()
{
return new JScrollPane();
}
/**
* This method configures scroll pane to contain list of comboBox's items
*/
protected void configureScroller()
{
scroller.getViewport().setView(list);
scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
}
/**
* This method configures popup menu that will be used to display Scrollpane
* with list of items inside of it.
*/
protected void configurePopup()
{
// FIXME: Need to implement
}
/*
* This method installs listeners that will listen to changes occuring
* in the combo box.
*/
protected void installComboBoxListeners()
{
// mouse listener that listens to mouse event in combo box
mouseListener = createMouseListener();
comboBox.addMouseListener(mouseListener);
// mouse listener that listens to mouse dragging events in the combo box
mouseMotionListener = createMouseMotionListener();
comboBox.addMouseMotionListener(mouseMotionListener);
// item listener listenening to selection events in the combo box
itemListener = createItemListener();
comboBox.addItemListener(itemListener);
propertyChangeListener = createPropertyChangeListener();
comboBox.addPropertyChangeListener(propertyChangeListener);
}
/**
* This method installs listeners that will listen to changes occuring in
* the comb box's data model
*
* @param model data model for the combo box for which to install listeners
*/
protected void installComboBoxModelListeners(ComboBoxModel model)
{
// list data listener to listen for ListDataEvents in combo box.
// This listener is now obsolete and nothing is done here
listDataListener = createListDataListener();
comboBox.getModel().addListDataListener(listDataListener);
}
/**
* DOCUMENT ME!
*/
protected void installKeyboardActions()
{
// FIXME: Need to implement
}
/**
* This method always returns false to indicate that items in the combo box
* list are not focus traversable.
*
* @return false
*/
public boolean isFocusTraversable()
{
return false;
}
/**
* DOCUMENT ME!
*
* @param direction DOCUMENT ME!
*/
protected void startAutoScrolling(int direction)
{
// FIXME: Need to implement
}
/**
* DOCUMENT ME!
*/
protected void stopAutoScrolling()
{
// FIXME: Need to implement
}
/**
* DOCUMENT ME!
*/
protected void autoScrollUp()
{
// FIXME: Need to implement
}
/**
* DOCUMENT ME!
*/
protected void autoScrollDown()
{
// FIXME: Need to implement
}
/**
* This method helps to delegate focus to the right component in the
* JComboBox. If the comboBox is editable then focus is sent to
* ComboBoxEditor, otherwise it is delegated to JComboBox.
*
* @param e MouseEvent
*/
protected void delegateFocus(MouseEvent e)
{
// FIXME: Need to implement
}
/**
* This method displays combo box popup if the popup is not currently shown
* on the screen and hides it if it is currently visible
*/
protected void togglePopup()
{
if (BasicComboPopup.this.isVisible())
hide();
else
show();
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected MouseEvent convertMouseEvent(MouseEvent e)
{
return null;
}
/**
* Returns required height of the popup such that number of items visible in
* it are equal to the maximum row count. By default
* comboBox.maximumRowCount=8
*
* @param maxRowCount number of maximum visible rows in the combo box's
* popup list of items
*
* @return height of the popup required to fit number of items equal to
* JComboBox.maximumRowCount.
*/
protected int getPopupHeightForRowCount(int maxRowCount)
{
int totalHeight = 0;
ListCellRenderer rend = list.getCellRenderer();
if (comboBox.getItemCount() < maxRowCount)
maxRowCount = comboBox.getItemCount();
for (int i = 0; i < maxRowCount; i++)
{
Component comp = rend.getListCellRendererComponent(list,
list.getModel()
.getElementAt(i),
-1, false, false);
Dimension dim = comp.getPreferredSize();
totalHeight += dim.height;
}
return totalHeight;
}
/**
* DOCUMENT ME!
*
* @param px DOCUMENT ME!
* @param py DOCUMENT ME!
* @param pw DOCUMENT ME!
* @param ph DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Rectangle computePopupBounds(int px, int py, int pw, int ph)
{
return new Rectangle(px, py, pw, ph);
}
/**
* This method changes the selection in the list to the item over which the
* mouse is currently located.
*
* @param anEvent MouseEvent
* @param shouldScroll DOCUMENT ME!
*/
protected void updateListBoxSelectionForEvent(MouseEvent anEvent,
boolean shouldScroll)
{
// FIXME: Need to implement
}
/**
* InvocationMouseHandler is a listener that listens to mouse events
* occuring in the combo box. Note that this listener doesn't listen to
* mouse events occuring in the popup portion of the combo box, it only
* listens to main combo box part(area that displays selected item). This
* listener is responsible for showing and hiding popup portion of the
* combo box.
*/
protected class InvocationMouseHandler extends MouseAdapter
{
/**
* Creates a new InvocationMouseHandler object.
*/
protected InvocationMouseHandler()
{
}
/**
* This method is invoked whenever mouse is being pressed over the main
* part of the combo box. This method will show popup if the popup is
* not shown on the screen right now, and it will hide popup otherwise.
*
* @param e MouseEvent that should be handled
*/
public void mousePressed(MouseEvent e)
{
if (comboBox.isEnabled())
togglePopup();
}
/**
* This method is invoked whenever mouse is released
*
* @param e MouseEvent that should be handled
*/
public void mouseReleased(MouseEvent e)
{
// FIXME: should handle dragging events here, if
// mouse was dragged and released over the list of combobox's items,
// then item over which it was released should be selected.
}
}
/**
* InvocationMouseMotionListener is a mouse listener that listens to mouse
* dragging events occuring in the combo box.
*/
protected class InvocationMouseMotionHandler extends MouseMotionAdapter
{
/**
* Creates a new InvocationMouseMotionHandler object.
*/
protected InvocationMouseMotionHandler()
{
}
public void mouseDragged(MouseEvent e)
{
}
}
/**
* ItemHandler is an item listener that listens to selection event occuring
* in the combo box. FIXME: should specify here what it does when item is
* selected or deselected in the combo box list.
*/
protected class ItemHandler extends Object implements ItemListener
{
/**
* Creates a new ItemHandler object.
*/
protected ItemHandler()
{
}
/**
* This method responds to the selection events occuring in the combo box.
*
* @param e ItemEvent specifying the combo box's selection
*/
public void itemStateChanged(ItemEvent e)
{
}
}
/**
* ListMouseHandler is a listener that listens to mouse events occuring in
* the combo box's list of items. This class is responsible for hiding
* popup portion of the combo box if the mouse is released inside the combo
* box's list.
*/
protected class ListMouseHandler extends MouseAdapter
{
protected ListMouseHandler()
{
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent anEvent)
{
int index = list.locationToIndex(anEvent.getPoint());
comboBox.setSelectedIndex(index);
hide();
}
}
/**
* ListMouseMotionHandler listens to mouse motion events occuring in the
* combo box's list. This class is responsible for highlighting items in
* the list when mouse is moved over them
*/
protected class ListMouseMotionHandler extends MouseMotionAdapter
{
protected ListMouseMotionHandler()
{
}
public void mouseMoved(MouseEvent anEvent)
{
// FIXME: Need to implement
// NOTE: the change isn't reflected in data model of the combo box.
// The items are only highlited, but not selected
}
}
/**
* This class listens to changes occuring in the bound properties of the
* combo box
*/
protected class PropertyChangeHandler extends Object
implements PropertyChangeListener
{
protected PropertyChangeHandler()
{
}
public void propertyChange(PropertyChangeEvent e)
{
if (e.getPropertyName().equals(JComboBox.RENDERER_CHANGED_PROPERTY))
{
list.setCellRenderer((ListCellRenderer) e.getNewValue());
revalidate();
repaint();
}
}
}
// ------ private helper methods --------------------
/**
* This method uninstalls listeners installed by the UI
*/
private void uninstallListeners()
{
uninstallListListeners();
uninstallComboBoxListeners();
uninstallComboBoxModelListeners(comboBox.getModel());
}
/**
* This method uninstalls Listeners registered with combo boxes list of
* items
*/
private void uninstallListListeners()
{
list.removeMouseListener(listMouseListener);
listMouseListener = null;
list.removeMouseMotionListener(listMouseMotionListener);
listMouseMotionListener = null;
}
/**
* This method uninstalls listeners listening to combo box associated with
* this popup menu
*/
private void uninstallComboBoxListeners()
{
comboBox.removeMouseListener(mouseListener);
mouseListener = null;
comboBox.removeMouseMotionListener(mouseMotionListener);
mouseMotionListener = null;
comboBox.removeItemListener(itemListener);
itemListener = null;
comboBox.removePropertyChangeListener(propertyChangeListener);
propertyChangeListener = null;
}
// --------------------------------------------------------------------
// The following classes are here only for backwards API compatibility
// They aren't used.
// --------------------------------------------------------------------
/**
* This class is not used any more.
*/
public class ListDataHandler extends Object implements ListDataListener
{
public ListDataHandler()
{
}
public void contentsChanged(ListDataEvent e)
{
}
public void intervalAdded(ListDataEvent e)
{
}
public void intervalRemoved(ListDataEvent e)
{
}
}
/**
* This class is not used anymore
*/
protected class ListSelectionHandler extends Object
implements ListSelectionListener
{
protected ListSelectionHandler()
{
}
public void valueChanged(ListSelectionEvent e)
{
}
}
/**
* This class is not used anymore
*/
public class InvocationKeyHandler extends KeyAdapter
{
public InvocationKeyHandler()
{
}
public void keyReleased(KeyEvent e)
{
}
}
}

View File

@ -0,0 +1,62 @@
/* BasicFormattedTextFieldUI.java
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
/**
* @since 1.4
*/
public class BasicFormattedTextFieldUI extends BasicTextFieldUI
{
public BasicFormattedTextFieldUI()
{
}
public static ComponentUI createUI(JComponent c)
{
return new BasicFormattedTextFieldUI();
}
protected String getPropertyPrefix()
{
return "FormattedTextField";
}
}

View File

@ -0,0 +1,61 @@
/* BasicPasswordFieldUI.java
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.text.Element;
import javax.swing.text.View;
public class BasicPasswordFieldUI extends BasicTextFieldUI
{
public BasicPasswordFieldUI()
{
}
public static ComponentUI createUI(JComponent c)
{
return new BasicPasswordFieldUI();
}
protected String getPropertyPrefix()
{
return "PasswordField";
}
}

View File

@ -0,0 +1,572 @@
/* SpinnerUI.java --
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JSpinner;
import javax.swing.Timer;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SpinnerUI;
/**
* DOCUMENT ME!
*
* @author Ka-Hing Cheung
*
* @see javax.swing.JSpinner
* @since 1.4
*/
public class BasicSpinnerUI extends SpinnerUI
{
/**
* Creates a new <code>ComponentUI</code> for the specified
* <code>JComponent</code>
*
* @param c DOCUMENT ME!
*
* @return a ComponentUI
*/
public static ComponentUI createUI(JComponent c)
{
return new BasicSpinnerUI();
}
/**
* Creates an editor component. Really, it just returns
* <code>JSpinner.getEditor()</code>
*
* @return a JComponent as an editor
*
* @see javax.swing.JSpinner#getEditor
*/
protected JComponent createEditor()
{
return spinner.getEditor();
}
/**
* Creates a <code>LayoutManager</code> that layouts the sub components. The
* subcomponents are identifies by the constraint "Next", "Previous" and
* "Editor"
*
* @return a LayoutManager
*
* @see java.awt.LayoutManager
*/
protected LayoutManager createLayout()
{
return new DefaultLayoutManager();
}
/**
* Creates the "Next" button
*
* @return the next button component
*/
protected Component createNextButton()
{
JButton button = new BasicArrowButton(BasicArrowButton.NORTH);
return button;
}
/**
* Creates the "Previous" button
*
* @return the previous button component
*/
protected Component createPreviousButton()
{
JButton button = new BasicArrowButton(BasicArrowButton.SOUTH);
return button;
}
/**
* Creates the <code>PropertyChangeListener</code> that will be attached by
* <code>installListeners</code>. It should watch for the "editor"
* property, when it's changed, replace the old editor with the new one,
* probably by calling <code>replaceEditor</code>
*
* @return a PropertyChangeListener
*
* @see #replaceEditor
*/
protected PropertyChangeListener createPropertyChangeListener()
{
return new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent evt)
{
// FIXME: Add check for enabled property change. Need to
// disable the buttons.
if ("editor".equals(evt.getPropertyName()))
BasicSpinnerUI.this.replaceEditor((JComponent) evt.getOldValue(),
(JComponent) evt.getNewValue());
}
};
}
/**
* Called by <code>installUI</code>. This should set various defaults
* obtained from <code>UIManager.getLookAndFeelDefaults</code>, as well as
* set the layout obtained from <code>createLayout</code>
*
* @see #javax.swing.UIManager#getLookAndFeelDefaults
* @see #createLayout
* @see #installUI
*/
protected void installDefaults()
{
/* most of it copied from BasicLabelUI, I don't know what keys are
available, so someone may want to update this. Hence: TODO
*/
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
/*
spinner.setForeground(defaults.getColor("Spinner.foreground"));
spinner.setBackground(defaults.getColor("Spinner.background"));
spinner.setFont(defaults.getFont("Spinner.font"));
spinner.setBorder(defaults.getBorder("Spinner.border"));
*/
spinner.setLayout(createLayout());
}
/*
* Called by <code>installUI</code>, which basically adds the
* <code>PropertyChangeListener</code> created by
* <code>createPropertyChangeListener</code>
*
* @see #createPropertyChangeListener
* @see #installUI
*/
protected void installListeners()
{
spinner.addPropertyChangeListener(listener);
}
/*
* Install listeners to the next button so that it increments the model
*/
protected void installNextButtonListeners(Component c)
{
c.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent evt)
{
if (! spinner.isEnabled())
return;
increment();
timer.setInitialDelay(500);
timer.start();
}
public void mouseReleased(MouseEvent evt)
{
timer.stop();
}
void increment()
{
Object next = BasicSpinnerUI.this.spinner.getNextValue();
if (next != null)
BasicSpinnerUI.this.spinner.getModel().setValue(next);
}
volatile boolean mouseDown = false;
Timer timer = new Timer(50,
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
increment();
}
});
});
}
/*
* Install listeners to the previous button so that it decrements the model
*/
protected void installPreviousButtonListeners(Component c)
{
c.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent evt)
{
if (! spinner.isEnabled())
return;
decrement();
timer.setInitialDelay(500);
timer.start();
}
public void mouseReleased(MouseEvent evt)
{
timer.stop();
}
void decrement()
{
Object prev = BasicSpinnerUI.this.spinner.getPreviousValue();
if (prev != null)
BasicSpinnerUI.this.spinner.getModel().setValue(prev);
}
volatile boolean mouseDown = false;
Timer timer = new Timer(50,
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
decrement();
}
});
});
}
/**
* Install this UI to the <code>JComponent</code>, which in reality, is a
* <code>JSpinner</code>. Calls <code>installDefaults</code>,
* <code>installListeners</code>, and also adds the buttons and editor.
*
* @param c DOCUMENT ME!
*
* @see #installDefaults
* @see #installListeners
* @see #createNextButton
* @see #createPreviousButton
* @see #createEditor
*/
public void installUI(JComponent c)
{
super.installUI(c);
spinner = (JSpinner) c;
installDefaults();
installListeners();
Component next = createNextButton();
Component previous = createPreviousButton();
installNextButtonListeners(next);
installPreviousButtonListeners(previous);
c.add(createEditor(), "Editor");
c.add(next, "Next");
c.add(previous, "Previous");
}
/**
* Replace the old editor with the new one
*
* @param oldEditor the old editor
* @param newEditor the new one to replace with
*/
protected void replaceEditor(JComponent oldEditor, JComponent newEditor)
{
spinner.remove(oldEditor);
spinner.add(newEditor);
}
/**
* The reverse of <code>installDefaults</code>. Called by
* <code>uninstallUI</code>
*/
protected void uninstallDefaults()
{
spinner.setLayout(null);
}
/**
* The reverse of <code>installListeners</code>, called by
* <code>uninstallUI</code>
*/
protected void uninstallListeners()
{
spinner.removePropertyChangeListener(listener);
}
/**
* Called when the current L&F is replaced with another one, should call
* <code>uninstallDefaults</code> and <code>uninstallListeners</code> as
* well as remove the next/previous buttons and the editor
*
* @param c DOCUMENT ME!
*/
public void uninstallUI(JComponent c)
{
super.uninstallUI(c);
uninstallDefaults();
uninstallListeners();
c.removeAll();
}
/** The spinner for this UI */
protected JSpinner spinner;
/** DOCUMENT ME! */
private PropertyChangeListener listener = createPropertyChangeListener();
/**
* DOCUMENT ME!
*/
private class DefaultLayoutManager implements LayoutManager
{
/**
* DOCUMENT ME!
*
* @param parent DOCUMENT ME!
*/
public void layoutContainer(Container parent)
{
synchronized (parent.getTreeLock())
{
Insets i = parent.getInsets();
boolean l2r = parent.getComponentOrientation().isLeftToRight();
/*
-------------- --------------
| | n | | n | |
| e | - | or | - | e |
| | p | | p | |
-------------- --------------
*/
Dimension e = minSize(editor);
Dimension n = minSize(next);
Dimension p = minSize(previous);
Dimension s = spinner.getPreferredSize();
int x = l2r ? i.left : i.right;
int y = i.top;
int w = Math.max(p.width, n.width);
int h = Math.max(p.height, n.height);
h = Math.max(h, e.height / 2);
int e_width = s.width - w;
if (l2r)
{
setBounds(editor, x, y + (s.height - e.height) / 2, e_width,
e.height);
x += e_width;
setBounds(next, x, y, w, h);
y += h;
setBounds(previous, x, y, w, h);
}
else
{
setBounds(next, x, y + (s.height - e.height) / 2, w, h);
y += h;
setBounds(previous, x, y, w, h);
x += w;
y -= h;
setBounds(editor, x, y, e_width, e.height);
}
}
}
/**
* DOCUMENT ME!
*
* @param parent DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Dimension minimumLayoutSize(Container parent)
{
Dimension d = new Dimension();
if (editor != null)
{
Dimension tmp = editor.getMinimumSize();
d.width += tmp.width;
d.height = tmp.height;
}
int nextWidth = 0;
int previousWidth = 0;
int otherHeight = 0;
if (next != null)
{
Dimension tmp = next.getMinimumSize();
nextWidth = tmp.width;
otherHeight += tmp.height;
}
if (previous != null)
{
Dimension tmp = previous.getMinimumSize();
previousWidth = tmp.width;
otherHeight += tmp.height;
}
d.height = Math.max(d.height, otherHeight);
d.width += Math.max(nextWidth, previousWidth);
return d;
}
/**
* DOCUMENT ME!
*
* @param parent DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Dimension preferredLayoutSize(Container parent)
{
Dimension d = new Dimension();
if (editor != null)
{
Dimension tmp = editor.getPreferredSize();
d.width += Math.max(tmp.width, 40);
d.height = tmp.height;
}
int nextWidth = 0;
int previousWidth = 0;
int otherHeight = 0;
if (next != null)
{
Dimension tmp = next.getPreferredSize();
nextWidth = tmp.width;
otherHeight += tmp.height;
}
if (previous != null)
{
Dimension tmp = previous.getPreferredSize();
previousWidth = tmp.width;
otherHeight += tmp.height;
}
d.height = Math.max(d.height, otherHeight);
d.width += Math.max(nextWidth, previousWidth);
return d;
}
/**
* DOCUMENT ME!
*
* @param child DOCUMENT ME!
*/
public void removeLayoutComponent(Component child)
{
if (child == editor)
editor = null;
else if (child == next)
next = null;
else if (previous == child)
previous = null;
}
/**
* DOCUMENT ME!
*
* @param name DOCUMENT ME!
* @param child DOCUMENT ME!
*/
public void addLayoutComponent(String name, Component child)
{
if ("Editor".equals(name))
editor = child;
else if ("Next".equals(name))
next = child;
else if ("Previous".equals(name))
previous = child;
}
/**
* DOCUMENT ME!
*
* @param c DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
private Dimension minSize(Component c)
{
if (c == null)
return new Dimension();
else
return c.getMinimumSize();
}
/**
* DOCUMENT ME!
*
* @param c DOCUMENT ME!
* @param x DOCUMENT ME!
* @param y DOCUMENT ME!
* @param w DOCUMENT ME!
* @param h DOCUMENT ME!
*/
private void setBounds(Component c, int x, int y, int w, int h)
{
if (c != null)
c.setBounds(x, y, w, h);
}
/** DOCUMENT ME! */
private Component editor;
/** DOCUMENT ME! */
private Component next;
/** DOCUMENT ME! */
private Component previous;
}
}

View File

@ -0,0 +1,301 @@
/* BasicTableHeaderUI.java
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import javax.swing.CellRendererPane;
import javax.swing.JComponent;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.TableHeaderUI;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class BasicTableHeaderUI
extends TableHeaderUI
{
public static ComponentUI createUI(JComponent h)
{
return new BasicTableHeaderUI();
}
protected JTableHeader header;
protected MouseInputListener mouseInputListener;
protected CellRendererPane rendererPane;
protected Border cellBorder;
class MouseInputHandler
implements MouseInputListener
{
public void mouseClicked(MouseEvent e) {}
public void mouseDragged(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
protected MouseInputListener createMouseInputListener()
{
return new MouseInputHandler();
}
public BasicTableHeaderUI()
{
mouseInputListener = createMouseInputListener();
}
protected void installDefaults()
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
header.setBackground(defaults.getColor("TableHeader.background"));
header.setForeground(defaults.getColor("TableHeader.foreground"));
header.setFont(defaults.getFont("TableHeader.font"));
cellBorder = defaults.getBorder("TableHeader.cellBorder");
}
protected void installKeyboardActions()
{
}
protected void installListeners()
{
header.addMouseListener(mouseInputListener);
}
public void installUI(JComponent c)
{
header = (JTableHeader) c;
installDefaults();
installKeyboardActions();
installListeners();
}
protected void uninstallDefaults()
{
header.setBackground(null);
header.setForeground(null);
header.setFont(null);
}
protected void uninstallKeyboardActions()
{
}
protected void uninstallListeners()
{
header.removeMouseListener(mouseInputListener);
}
public void uninstallUI(JComponent c)
{
uninstallListeners();
uninstallKeyboardActions();
uninstallDefaults();
}
public void paint(Graphics gfx, JComponent c)
{
TableColumnModel cmod = header.getColumnModel();
int ncols = cmod.getColumnCount();
if (ncols == 0)
return;
Rectangle clip = gfx.getClipBounds();
TableCellRenderer defaultRend = header.getDefaultRenderer();
for (int i = 0; i < ncols; ++i)
{
Rectangle bounds = header.getHeaderRect(i);
if (bounds.intersects(clip))
{
TableColumn col = cmod.getColumn(i);
TableCellRenderer rend = col.getHeaderRenderer();
if (rend == null)
rend = defaultRend;
Object val = col.getHeaderValue();
Component comp = rend.getTableCellRendererComponent(header.getTable(),
val,
false, // isSelected
false, // isFocused
-1, i);
comp.setFont(header.getFont());
comp.setBackground(header.getBackground());
comp.setForeground(header.getForeground());
if (comp instanceof JComponent)
((JComponent)comp).setBorder(cellBorder);
gfx.translate(bounds.x, bounds.y);
comp.setSize(bounds.width, bounds.height);
comp.setLocation(0,0);
comp.paint(gfx);
gfx.translate(-bounds.x, -bounds.y);
}
}
}
public Dimension getMaximumSize(JComponent c)
{
TableColumnModel cmod = header.getColumnModel();
TableCellRenderer defaultRend = header.getDefaultRenderer();
int ncols = cmod.getColumnCount();
int spacing = 0;
Dimension ret = getPreferredSize(c);
if (header.getTable() != null
&& header.getTable().getInterCellSpacing() != null)
spacing = header.getTable().getInterCellSpacing().width;
ret.width = 0;
for (int i = 0; i < ncols; ++i)
{
TableColumn col = cmod.getColumn(i);
TableCellRenderer rend = col.getHeaderRenderer();
if (rend == null)
rend = defaultRend;
Object val = col.getHeaderValue();
Component comp = rend.getTableCellRendererComponent(header.getTable(),
val,
false, // isSelected
false, // isFocused
-1, i);
comp.setFont(header.getFont());
comp.setBackground(header.getBackground());
comp.setForeground(header.getForeground());
if (comp instanceof JComponent)
((JComponent)comp).setBorder(cellBorder);
Dimension d = comp.getMaximumSize();
ret.width += col.getMaxWidth();
ret.height = Math.max(ret.height, d.height);
ret.width += spacing;
}
return ret;
}
public Dimension getMinimumSize(JComponent c)
{
TableColumnModel cmod = header.getColumnModel();
TableCellRenderer defaultRend = header.getDefaultRenderer();
int ncols = cmod.getColumnCount();
int spacing = 0;
Dimension ret = getPreferredSize(c);
if (header.getTable() != null
&& header.getTable().getInterCellSpacing() != null)
spacing = header.getTable().getInterCellSpacing().width;
ret.width = 0;
for (int i = 0; i < ncols; ++i)
{
TableColumn col = cmod.getColumn(i);
TableCellRenderer rend = col.getHeaderRenderer();
if (rend == null)
rend = defaultRend;
Object val = col.getHeaderValue();
Component comp = rend.getTableCellRendererComponent(header.getTable(),
val,
false, // isSelected
false, // isFocused
-1, i);
comp.setFont(header.getFont());
comp.setBackground(header.getBackground());
comp.setForeground(header.getForeground());
if (comp instanceof JComponent)
((JComponent)comp).setBorder(cellBorder);
Dimension d = comp.getMinimumSize();
ret.width += col.getMinWidth();
ret.width += spacing;
ret.height = Math.max(ret.height, d.height);
}
return ret;
}
public Dimension getPreferredSize(JComponent c)
{
TableColumnModel cmod = header.getColumnModel();
TableCellRenderer defaultRend = header.getDefaultRenderer();
int ncols = cmod.getColumnCount();
Dimension ret = new Dimension(0,0);
int spacing = 0;
if (header.getTable() != null
&& header.getTable().getInterCellSpacing() != null)
spacing = header.getTable().getInterCellSpacing().width;
for (int i = 0; i < ncols; ++i)
{
TableColumn col = cmod.getColumn(i);
TableCellRenderer rend = col.getHeaderRenderer();
if (rend == null)
rend = defaultRend;
Object val = col.getHeaderValue();
Component comp = rend.getTableCellRendererComponent(header.getTable(),
val,
false, // isSelected
false, // isFocused
-1, i);
comp.setFont(header.getFont());
comp.setBackground(header.getBackground());
comp.setForeground(header.getForeground());
if (comp instanceof JComponent)
((JComponent)comp).setBorder(cellBorder);
Dimension d = comp.getPreferredSize();
ret.width += d.width;
ret.width += spacing;
ret.height = Math.max(d.height, ret.height);
}
return ret;
}
}

View File

@ -0,0 +1,374 @@
/* BasicTableUI.java
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import javax.swing.CellRendererPane;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.TableUI;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
public class BasicTableUI
extends TableUI
{
public static ComponentUI createUI(JComponent comp)
{
return new BasicTableUI();
}
protected FocusListener focusListener;
protected KeyListener keyListener;
protected MouseInputListener mouseInputListener;
protected CellRendererPane rendererPane;
protected JTable table;
class FocusHandler implements FocusListener
{
public void focusGained(FocusEvent e)
{
}
public void focusLost(FocusEvent e)
{
}
}
class KeyHandler implements KeyListener
{
public void keyPressed(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
}
class MouseInputHandler implements MouseInputListener
{
Point begin, curr;
private int getRowForPoint(Point p)
{
int y0 = table.getLocation().y;
int nrows = table.getRowCount();
Dimension gap = table.getInterCellSpacing();
int height = table.getRowHeight() + (gap == null ? 0 : gap.height);
int y = p.y;
for (int i = 0; i < nrows; ++i)
{
if (0 <= y && y < height)
return i;
y -= height;
}
return -1;
}
private int getColForPoint(Point p)
{
int x0 = table.getLocation().x;
int ncols = table.getColumnCount();
Dimension gap = table.getInterCellSpacing();
TableColumnModel cols = table.getColumnModel();
int x = p.x;
for (int i = 0; i < ncols; ++i)
{
int width = cols.getColumn(i).getWidth() + (gap == null ? 0 : gap.width);
if (0 <= x && x < width)
return i;
x -= width;
}
return -1;
}
private void updateSelection()
{
if (table.getRowSelectionAllowed())
{
int lo_row = getRowForPoint(begin);
int hi_row = getRowForPoint(curr);
ListSelectionModel rowModel = table.getSelectionModel();
if (lo_row != -1 && hi_row != -1)
rowModel.setSelectionInterval(lo_row, hi_row);
}
if (table.getColumnSelectionAllowed())
{
int lo_col = getColForPoint(begin);
int hi_col = getColForPoint(curr);
ListSelectionModel colModel = table.getColumnModel().getSelectionModel();
if (lo_col != -1 && hi_col != -1)
colModel.setSelectionInterval(lo_col, hi_col);
}
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseDragged(MouseEvent e)
{
curr = new Point(e.getX(), e.getY());
updateSelection();
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mouseMoved(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
begin = new Point(e.getX(), e.getY());
curr = new Point(e.getX(), e.getY());
updateSelection();
}
public void mouseReleased(MouseEvent e)
{
begin = null;
curr = null;
}
}
protected FocusListener createFocusListener()
{
return new FocusHandler();
}
protected KeyListener createKeyListener()
{
return new KeyHandler();
}
protected MouseInputListener createMouseInputListener()
{
return new MouseInputHandler();
}
public Dimension getMaximumSize(JComponent comp)
{
return getPreferredSize(comp);
}
public Dimension getMinimumSize(JComponent comp)
{
return getPreferredSize(comp);
}
public Dimension getPreferredSize(JComponent comp)
{
int width = table.getColumnModel().getTotalColumnWidth();
int height = table.getRowCount() * table.getRowHeight();
return new Dimension(width, height);
}
protected void installDefaults()
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
table.setFont(defaults.getFont("Table.font"));
table.setGridColor(defaults.getColor("Table.gridColor"));
table.setForeground(defaults.getColor("Table.foreground"));
table.setBackground(defaults.getColor("Table.background"));
table.setSelectionForeground(defaults.getColor("Table.selectionForeground"));
table.setSelectionBackground(defaults.getColor("Table.selectionBackground"));
table.setOpaque(true);
}
protected void installKeyboardActions()
{
}
protected void installListeners()
{
table.addFocusListener(focusListener);
table.addKeyListener(keyListener);
table.addMouseListener(mouseInputListener);
}
protected void uninstallDefaults()
{
table.setFont(null);
table.setGridColor(null);
table.setForeground(null);
table.setBackground(null);
table.setSelectionForeground(null);
table.setSelectionBackground(null);
}
protected void uninstallKeyboardActions()
{
}
protected void uninstallListeners()
{
table.removeFocusListener(focusListener);
table.removeKeyListener(keyListener);
table.removeMouseListener(mouseInputListener);
}
public void installUI(JComponent comp)
{
table = (JTable)comp;
focusListener = createFocusListener();
keyListener = createKeyListener();
mouseInputListener = createMouseInputListener();
installDefaults();
installKeyboardActions();
installListeners();
}
public void uninstallUI(JComponent c)
{
uninstallListeners();
uninstallKeyboardActions();
uninstallDefaults();
}
public void paint(Graphics gfx, JComponent ignored)
{
int ncols = table.getColumnCount();
int nrows = table.getRowCount();
if (nrows == 0 || ncols == 0)
return;
Rectangle clip = gfx.getClipBounds();
TableColumnModel cols = table.getColumnModel();
int height = table.getRowHeight();
int x0 = 0, y0 = 0;
int x = x0;
int y = y0;
Dimension gap = table.getInterCellSpacing();
int ymax = clip.y + clip.height;
int xmax = clip.x + clip.width;
// paint the cell contents
for (int c = 0; c < ncols && x < xmax; ++c)
{
y = y0;
TableColumn col = cols.getColumn(c);
int width = col.getWidth();
int modelCol = col.getModelIndex();
for (int r = 0; r < nrows && y < ymax; ++r)
{
Rectangle bounds = new Rectangle(x, y, width, height);
if (bounds.intersects(clip))
{
TableCellRenderer rend = table.getCellRenderer(r, c);
Component comp = table.prepareRenderer(rend, r, c);
gfx.translate(x, y);
comp.setBounds(new Rectangle(0, 0, width, height));
comp.paint(gfx);
gfx.translate(-x, -y);
}
y += height;
if (gap != null)
y += gap.height;
}
x += width;
if (gap != null)
x += gap.width;
}
// tighten up the x and y max bounds
ymax = y;
xmax = x;
Color grid = table.getGridColor();
// paint vertical grid lines
if (grid != null && table.getShowVerticalLines())
{
x = x0;
Color save = gfx.getColor();
gfx.setColor(grid);
boolean paintedLine = false;
for (int c = 0; c < ncols && x < xmax; ++c)
{
x += cols.getColumn(c).getWidth();;
if (gap != null)
x += gap.width;
gfx.drawLine(x, y0, x, ymax);
paintedLine = true;
}
gfx.setColor(save);
}
// paint horizontal grid lines
if (grid != null && table.getShowHorizontalLines())
{
y = y0;
Color save = gfx.getColor();
gfx.setColor(grid);
boolean paintedLine = false;
for (int r = 0; r < nrows && y < ymax; ++r)
{
y += height;
if (gap != null)
y += gap.height;
gfx.drawLine(x0, y, xmax, y);
paintedLine = true;
}
gfx.setColor(save);
}
}
}

View File

@ -0,0 +1,69 @@
/* BasicTextAreaUI.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.beans.PropertyChangeEvent;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.text.Element;
import javax.swing.text.PlainView;
import javax.swing.text.View;
public class BasicTextAreaUI extends BasicTextUI
{
public static ComponentUI createUI(JComponent comp)
{
return new BasicTextAreaUI();
}
public BasicTextAreaUI()
{
}
public View create(Element elem)
{
return new PlainView(elem);
}
protected String getPropertyPrefix()
{
return "TextArea";
}
}

View File

@ -0,0 +1,287 @@
/* BasicToolTipUI.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JToolTip;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ToolTipUI;
/**
* This is the Basic Look and Feel UI class for JToolTip.
*/
public class BasicToolTipUI extends ToolTipUI
{
/** The default Border around the JToolTip. */
private static Border defaultBorder = new Border()
{
// FIXME: This needs to go into Basic Look and Feel
// defaults.
/**
* This method returns the border insets.
*
* @param c The Component to find Border insets for.
*
* @return The Border insets.
*/
public Insets getBorderInsets(Component c)
{
return new Insets(4, 4, 4, 4);
}
/**
* This method returns whether the border is opaque.
*
* @return Whether the border is opaque.
*/
public boolean isBorderOpaque()
{
return false;
}
/**
* This method paints the border.
*
* @param c The Component to paint this border around.
* @param g The Graphics object to paint with.
* @param x The x coordinate to start painting at.
* @param y The y coordinate to start painting at.
* @param w The width of the Component.
* @param y The height of the Component.
*/
public void paintBorder(Component c, Graphics g, int x, int y, int w,
int h)
{
Color saved = g.getColor();
g.setColor(Color.BLACK);
g.drawRect(0, 0, w - 1, h - 1);
g.setColor(saved);
}
};
/** The shared instance of BasicToolTipUI used for all ToolTips. */
private static BasicToolTipUI shared;
/**
* Creates a new BasicToolTipUI object.
*/
public BasicToolTipUI()
{
super();
}
/**
* This method creates a new BasicToolTip UI for the given
* JComponent.
*
* @param c The JComponent to create a UI for.
*
* @return A BasicToolTipUI that can be used by the given JComponent.
*/
public static ComponentUI createUI(JComponent c)
{
if (shared == null)
shared = new BasicToolTipUI();
return shared;
}
/**
* This method returns the msximum size of the given JComponent.
*
* @param c The JComponent to find a maximum size for.
*
* @return The maximum size.
*/
public Dimension getMaximumSize(JComponent c)
{
return getPreferredSize(c);
}
/**
* This method returns the minimum size of the given JComponent.
*
* @param c The JComponent to find a minimum size for.
*
* @return The minimum size.
*/
public Dimension getMinimumSize(JComponent c)
{
return getPreferredSize(c);
}
/**
* This method returns the preferred size of the given JComponent.
*
* @param c The JComponent to find a preferred size for.
*
* @return The preferred size.
*/
public Dimension getPreferredSize(JComponent c)
{
JToolTip tip = (JToolTip) c;
Rectangle vr = new Rectangle();
Rectangle ir = new Rectangle();
Rectangle tr = new Rectangle();
Insets insets = tip.getInsets();
FontMetrics fm = tip.getToolkit().getFontMetrics(tip.getFont());
SwingUtilities.layoutCompoundLabel(tip, fm, tip.getTipText(), null,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER, vr, ir, tr, 0);
return new Dimension(insets.left + tr.width + insets.right,
insets.top + tr.height + insets.bottom);
}
/**
* This method installs the defaults for the given JComponent.
*
* @param c The JComponent to install defaults for.
*/
protected void installDefaults(JComponent c)
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
c.setBackground(defaults.getColor("ToolTip.background"));
c.setForeground(defaults.getColor("ToolTip.foreground"));
c.setFont(defaults.getFont("ToolTip.font"));
c.setBorder(defaultBorder);
}
/**
* This method installs the listeners for the given JComponent.
*
* @param c The JComponent to install listeners for.
*/
protected void installListeners(JComponent c)
{
}
/**
* This method installs the UI for the given JComponent.
*
* @param c The JComponent to install the UI for.
*/
public void installUI(JComponent c)
{
c.setOpaque(true);
installDefaults(c);
installListeners(c);
}
/**
* This method paints the given JComponent with the given Graphics object.
*
* @param g The Graphics object to paint with.
* @param c The JComponent to paint.
*/
public void paint(Graphics g, JComponent c)
{
JToolTip tip = (JToolTip) c;
String text = tip.getTipText();
if (text == null)
return;
Rectangle vr = new Rectangle();
vr = SwingUtilities.calculateInnerArea(tip, vr);
Rectangle ir = new Rectangle();
Rectangle tr = new Rectangle();
FontMetrics fm = tip.getToolkit().getFontMetrics(tip.getFont());
SwingUtilities.layoutCompoundLabel(tip, fm, tip.getTipText(), null,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER, vr, ir, tr, 0);
Color saved = g.getColor();
g.setColor(Color.BLACK);
g.drawString(text, vr.x, vr.y + fm.getAscent());
g.setColor(saved);
}
/**
* This method uninstalls the defaults for the given JComponent.
*
* @param c The JComponent to uninstall defaults for.
*/
protected void uninstallDefaults(JComponent c)
{
c.setForeground(null);
c.setBackground(null);
c.setFont(null);
c.setBorder(null);
}
/**
* This method uninstalls listeners for the given JComponent.
*
* @param c The JComponent to uninstall listeners for.
*/
protected void uninstallListeners(JComponent c)
{
}
/**
* This method uninstalls the UI for the given JComponent.
*
* @param c The JComponent to uninstall.
*/
public void uninstallUI(JComponent c)
{
uninstallDefaults(c);
uninstallListeners(c);
}
}

View File

@ -0,0 +1,103 @@
/* ComboPopup.java
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JList;
public interface ComboPopup
{
/**
* This method display popup menu containing list of JComboBox's items to
* the screen
*/
void show();
/**
* This method hides popup menu with list of JComboBox's item from the
* screen
*/
void hide();
/**
* Retursn true if popup menu with JComboBOx's item is currently visible on
* the screen and false otherwise
*
* @return true if JComboBox's popup menu with list of items is currently
* visible on the screen and false otherwise.
*/
boolean isVisible();
/**
* Return JList that is used to draw cells of the JComboBox.
*
* @return JList that is used to draw cells of the JcomboBox
*/
JList getList();
/**
* This method returns MouseListener that listen's to mouse events occuring
* in the combo box
*
* @return MouseListenere
*/
MouseListener getMouseListener();
/**
* This method returns MouseListener that listen's to mouse events occuring
* in the combo box.
*
* @return MouseMotionListener
*/
MouseMotionListener getMouseMotionListener();
/**
* This method returns KeyListener that listen's to key events occuring in
* the combo box.
*
* @return KeyListener
*/
KeyListener getKeyListener();
/* This method removes any listeners that were installed */
void uninstallingUI();
}

View File

@ -0,0 +1,192 @@
/* SimpleAttributeSet.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.text;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
import java.lang.Cloneable;
public class SimpleAttributeSet
implements MutableAttributeSet, Serializable, Cloneable
{
Hashtable tab;
static AttributeSet EMPTY = new SimpleAttributeSet();
public SimpleAttributeSet()
{
this(null);
}
public SimpleAttributeSet(AttributeSet a)
{
tab = new Hashtable();
addAttributes(a);
}
public void addAttribute(Object name, Object value)
{
tab.put(name, value);
}
public void addAttributes(AttributeSet attributes)
{
Enumeration e = attributes.getAttributeNames();
while (e.hasMoreElements())
{
Object name = e.nextElement();
Object val = attributes.getAttribute(name);
tab.put(name, val);
}
}
public Object clone()
{
SimpleAttributeSet s = new SimpleAttributeSet();
s.tab = (Hashtable) tab.clone();
return s;
}
public boolean containsAttribute(Object name, Object value)
{
return tab.containsKey(name)
&& tab.get(name).equals(value);
}
public boolean containsAttributes(AttributeSet attributes)
{
Enumeration e = attributes.getAttributeNames();
while (e.hasMoreElements())
{
Object name = e.nextElement();
Object val = attributes.getAttribute(name);
if (! containsAttribute(name, val))
return false;
}
return true;
}
public AttributeSet copyAttributes()
{
return (AttributeSet) clone();
}
public boolean equals(Object obj)
{
return (obj != null)
&& (obj instanceof SimpleAttributeSet)
&& ((SimpleAttributeSet)obj).tab.equals(this.tab);
}
public Object getAttribute(Object name)
{
Object val = tab.get(name);
if (val != null)
return val;
Object p = getResolveParent();
if (p != null && p instanceof AttributeSet)
return (((AttributeSet)p).getAttribute(name));
return null;
}
public int getAttributeCount()
{
return tab.size();
}
public Enumeration getAttributeNames()
{
return tab.keys();
}
public AttributeSet getResolveParent()
{
return (AttributeSet) tab.get(ResolveAttribute);
}
public int hashCode()
{
return tab.hashCode();
}
public boolean isDefined(Object attrName)
{
return tab.containsKey(attrName);
}
public boolean isEmpty()
{
return tab.isEmpty();
}
public boolean isEqual(AttributeSet attr)
{
return this.equals(attr);
}
public void removeAttribute(Object name)
{
tab.remove(name);
}
public void removeAttributes(AttributeSet attributes)
{
removeAttributes(attributes.getAttributeNames());
}
public void removeAttributes(Enumeration names)
{
while (names.hasMoreElements())
{
removeAttribute(names.nextElement());
}
}
public void setResolveParent(AttributeSet parent)
{
addAttribute(ResolveAttribute, parent);
}
public String toString()
{
return tab.toString();
}
}

View File

@ -0,0 +1,439 @@
/* StyleConstants.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.text;
import java.awt.Color;
import java.awt.Component;
import javax.swing.Icon;
public class StyleConstants
{
String keyname;
private StyleConstants(String k)
{
keyname = k;
}
public String toString()
{
return keyname;
}
public static int ALIGN_CENTER;
public static int ALIGN_JUSTIFIED;
public static int ALIGN_LEFT;
public static int ALIGN_RIGHT;
public static Object Background = CharacterConstants.Background;
public static Object BidiLevel = CharacterConstants.BidiLevel;
public static Object Bold = CharacterConstants.Bold;
public static Object ComponentAttribute = CharacterConstants.ComponentAttribute;
public static Object FontFamily = CharacterConstants.Family;
public static Object FontSize = CharacterConstants.Size;
public static Object Foreground = CharacterConstants.Foreground;
public static Object IconAttribute = CharacterConstants.IconAttribute;
public static Object Italic = CharacterConstants.Italic;
public static Object StrikeThrough = CharacterConstants.StrikeThrough;
public static Object Subscript = CharacterConstants.Subscript;
public static Object Superscript = CharacterConstants.Superscript;
public static Object Underline = CharacterConstants.Underline;
public static Object Alignment = ParagraphConstants.Alignment;
public static Object FirstLineIndent = ParagraphConstants.FirstLineIndent;
public static Object LeftIndent = ParagraphConstants.LeftIndent;
public static Object LineSpacing = ParagraphConstants.LineSpacing;
public static Object Orientation = ParagraphConstants.Orientation;
public static Object RightIndent = ParagraphConstants.RightIndent;
public static Object SpaceAbove = ParagraphConstants.SpaceAbove;
public static Object SpaceBelow = ParagraphConstants.SpaceBelow;
public static Object TabSet = ParagraphConstants.TabSet;
public static String ComponentElementName = new String("component");
public static String IconElementName = new String("icon");
public static Object ComposedTextAttribute = new StyleConstants("composed text");
public static Object ModelAttribute = new StyleConstants("model");
public static Object NameAttribute = new StyleConstants("name");
public static Object ResolveAttribute = new StyleConstants("resolver");
public static int getAlignment(AttributeSet a)
{
if (a.isDefined(Alignment))
return ((Integer)a.getAttribute(Alignment)).intValue();
else
return ALIGN_LEFT;
}
public static Color getBackground(AttributeSet a)
{
if (a.isDefined(Background))
return (Color) a.getAttribute(Background);
else
return Color.BLACK;
}
public static int getBidiLevel(AttributeSet a)
{
if (a.isDefined(BidiLevel))
return ((Integer)a.getAttribute(BidiLevel)).intValue();
else
return 0;
}
public static Component getComponent(AttributeSet a)
{
if (a.isDefined(ComponentAttribute))
return (Component) a.getAttribute(ComponentAttribute);
else
return (Component) null;
}
public static float getFirstLineIndent(AttributeSet a)
{
if (a.isDefined(FirstLineIndent))
return ((Float)a.getAttribute(FirstLineIndent)).floatValue();
else
return 0.f;
}
public static String getFontFamily(AttributeSet a)
{
if (a.isDefined(FontFamily))
return (String) a.getAttribute(FontFamily);
else
return "Monospaced";
}
public static int getFontSize(AttributeSet a)
{
if (a.isDefined(FontSize))
return ((Integer)a.getAttribute(FontSize)).intValue();
else
return 12;
}
public static Color getForeground(AttributeSet a)
{
if (a.isDefined(Foreground))
return (Color) a.getAttribute(Foreground);
else
return Color.BLACK;
}
public static Icon getIcon(AttributeSet a)
{
if (a.isDefined(IconAttribute))
return (Icon) a.getAttribute(IconAttribute);
else
return (Icon) null;
}
public static float getLeftIndent(AttributeSet a)
{
if (a.isDefined(LeftIndent))
return ((Float)a.getAttribute(LeftIndent)).floatValue();
else
return 0.f;
}
public static float getLineSpacing(AttributeSet a)
{
if (a.isDefined(LineSpacing))
return ((Float)a.getAttribute(LineSpacing)).floatValue();
else
return 0.f;
}
public static float getRightIndent(AttributeSet a)
{
if (a.isDefined(RightIndent))
return ((Float)a.getAttribute(RightIndent)).floatValue();
else
return 0.f;
}
public static float getSpaceAbove(AttributeSet a)
{
if (a.isDefined(SpaceAbove))
return ((Float)a.getAttribute(SpaceAbove)).floatValue();
else
return 0.f;
}
public static float getSpaceBelow(AttributeSet a)
{
if (a.isDefined(SpaceBelow))
return ((Float)a.getAttribute(SpaceBelow)).floatValue();
else
return 0.f;
}
public static javax.swing.text.TabSet getTabSet(AttributeSet a)
{
if (a.isDefined(StyleConstants.TabSet))
return (javax.swing.text.TabSet) a.getAttribute(StyleConstants.TabSet);
else
return (javax.swing.text.TabSet) null;
}
public static boolean isBold(AttributeSet a)
{
if (a.isDefined(Bold))
return ((Boolean) a.getAttribute(Bold)).booleanValue();
else
return false;
}
public static boolean isItalic(AttributeSet a)
{
if (a.isDefined(Italic))
return ((Boolean) a.getAttribute(Italic)).booleanValue();
else
return false;
}
public static boolean isStrikeThrough(AttributeSet a)
{
if (a.isDefined(StrikeThrough))
return ((Boolean) a.getAttribute(StrikeThrough)).booleanValue();
else
return false;
}
public static boolean isSubscript(AttributeSet a)
{
if (a.isDefined(Subscript))
return ((Boolean) a.getAttribute(Subscript)).booleanValue();
else
return false;
}
public static boolean isSuperscript(AttributeSet a)
{
if (a.isDefined(Superscript))
return ((Boolean) a.getAttribute(Superscript)).booleanValue();
else
return false;
}
public static boolean isUnderline(AttributeSet a)
{
if (a.isDefined(Underline))
return ((Boolean) a.getAttribute(Underline)).booleanValue();
else
return false;
}
public static void setAlignment(MutableAttributeSet a, int align)
{
a.addAttribute(Alignment, new Integer(align));
}
public static void setBackground(MutableAttributeSet a, Color fg)
{
a.addAttribute(Background, fg);
}
public static void setBidiLevel(MutableAttributeSet a, int lev)
{
a.addAttribute(BidiLevel, new Integer(lev));
}
public static void setBold(MutableAttributeSet a, boolean b)
{
a.addAttribute(Bold, new Boolean(b));
}
public static void setComponent(MutableAttributeSet a, Component c)
{
a.addAttribute(ComponentAttribute, c);
}
public static void setFirstLineIndent(MutableAttributeSet a, float i)
{
a.addAttribute(FirstLineIndent, new Float(i));
}
public static void setFontFamily(MutableAttributeSet a, String fam)
{
a.addAttribute(FontFamily, fam);
}
public static void setFontSize(MutableAttributeSet a, int s)
{
a.addAttribute(FontSize, new Integer(s));
}
public static void setForeground(MutableAttributeSet a, Color fg)
{
a.addAttribute(Foreground, fg);
}
public static void setIcon(MutableAttributeSet a, Icon c)
{
a.addAttribute(IconAttribute, c);
}
public static void setItalic(MutableAttributeSet a, boolean b)
{
a.addAttribute(Italic, new Boolean(b));
}
public static void setLeftIndent(MutableAttributeSet a, float i)
{
a.addAttribute(LeftIndent, new Float(i));
}
public static void setLineSpacing(MutableAttributeSet a, float i)
{
a.addAttribute(LineSpacing, new Float(i));
}
public static void setRightIndent(MutableAttributeSet a, float i)
{
a.addAttribute(RightIndent, new Float(i));
}
public static void setSpaceAbove(MutableAttributeSet a, float i)
{
a.addAttribute(SpaceAbove, new Float(i));
}
public static void setSpaceBelow(MutableAttributeSet a, float i)
{
a.addAttribute(SpaceBelow, new Float(i));
}
public static void setStrikeThrough(MutableAttributeSet a, boolean b)
{
a.addAttribute(StrikeThrough, new Boolean(b));
}
public static void setSubscript(MutableAttributeSet a, boolean b)
{
a.addAttribute(Subscript, new Boolean(b));
}
public static void setSuperscript(MutableAttributeSet a, boolean b)
{
a.addAttribute(Superscript, new Boolean(b));
}
public static void setTabSet(MutableAttributeSet a, javax.swing.text.TabSet tabs)
{
a.addAttribute(StyleConstants.TabSet, tabs);
}
public static void setUnderline(MutableAttributeSet a, boolean b)
{
a.addAttribute(Underline, new Boolean(b));
}
// The remainder are so-called "typesafe enumerations" which
// alias subsets of the above constants.
public static class CharacterConstants
extends StyleConstants
implements AttributeSet.CharacterAttribute
{
private CharacterConstants(String k)
{
super(k);
}
public static Object Background = ColorConstants.Background;
public static Object BidiLevel = new CharacterConstants("bidiLevel");
public static Object Bold = FontConstants.Bold;
public static Object ComponentAttribute = new CharacterConstants("component");
public static Object Family = FontConstants.Family;
public static Object Size = FontConstants.Size;
public static Object Foreground = ColorConstants.Foreground;
public static Object IconAttribute = new CharacterConstants("icon");
public static Object Italic = FontConstants.Italic;
public static Object StrikeThrough = new CharacterConstants("strikethrough");
public static Object Subscript = new CharacterConstants("subscript");
public static Object Superscript = new CharacterConstants("superscript");
public static Object Underline = new CharacterConstants("underline");
}
public static class ColorConstants
extends StyleConstants
implements AttributeSet.ColorAttribute, AttributeSet.CharacterAttribute
{
private ColorConstants(String k)
{
super(k);
}
public static Object Foreground = new ColorConstants("foreground");
public static Object Background = new ColorConstants("background");
}
public static class FontConstants
extends StyleConstants
implements AttributeSet.FontAttribute, AttributeSet.CharacterAttribute
{
private FontConstants(String k)
{
super(k);
}
public static Object Bold = new FontConstants("bold");
public static Object Family = new FontConstants("family");
public static Object Italic = new FontConstants("italic");
public static Object Size = new FontConstants("size");
}
public static class ParagraphConstants
extends StyleConstants
implements AttributeSet.ParagraphAttribute
{
private ParagraphConstants(String k)
{
super(k);
}
public static Object Alignment = new ParagraphConstants("Alignment");
public static Object FirstLineIndent = new ParagraphConstants("FirstLineIndent");
public static Object LeftIndent = new ParagraphConstants("LeftIndent");
public static Object LineSpacing = new ParagraphConstants("LineSpacing");
public static Object Orientation = new ParagraphConstants("Orientation");
public static Object RightIndent = new ParagraphConstants("RightIndent");
public static Object SpaceAbove = new ParagraphConstants("SpaceAbove");
public static Object SpaceBelow = new ParagraphConstants("SpaceBelow");
public static Object TabSet = new ParagraphConstants("TabSet");
}
}

View File

@ -0,0 +1,697 @@
/* StyleContext.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.text;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Toolkit;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import javax.swing.event.EventListenerList;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Hashtable;
public class StyleContext
implements Serializable, AbstractDocument.AttributeContext
{
public class NamedStyle
implements Serializable, Style
{
protected ChangeEvent changeEvent;
protected EventListenerList listenerList;
AttributeSet attributes;
String name;
public NamedStyle()
{
this(null, null);
}
public NamedStyle(Style parent)
{
this(null, parent);
}
public NamedStyle(String name, Style parent)
{
this.name = name;
this.attributes = getEmptySet();
this.changeEvent = new ChangeEvent(this);
this.listenerList = new EventListenerList();
setResolveParent(parent);
}
public String getName()
{
return name;
}
public void setName(String n)
{
name = n;
fireStateChanged();
}
public void addChangeListener(ChangeListener l)
{
listenerList.add(ChangeListener.class, l);
}
public void removeChangeListener(ChangeListener l)
{
listenerList.remove(ChangeListener.class, l);
}
public EventListener[] getListeners(Class listenerType)
{
return listenerList.getListeners(listenerType);
}
public ChangeListener[] getChangeListeners()
{
return (ChangeListener[]) getListeners(ChangeListener.class);
}
protected void fireStateChanged()
{
ChangeListener[] listeners = getChangeListeners();
for (int i = 0; i < listeners.length; ++i)
{
listeners[i].stateChanged(changeEvent);
}
}
public void addAttribute(Object name, Object value)
{
attributes = StyleContext.this.addAttribute(attributes, name, value);
fireStateChanged();
}
public void addAttributes(AttributeSet attr)
{
attributes = StyleContext.this.addAttributes(attributes, attr);
fireStateChanged();
}
public boolean containsAttribute(Object name, Object value)
{
return attributes.containsAttribute(name, value);
}
public boolean containsAttributes(AttributeSet attrs)
{
return attributes.containsAttributes(attrs);
}
public AttributeSet copyAttributes()
{
return attributes.copyAttributes();
}
public Object getAttribute(Object attrName)
{
return attributes.getAttribute(attrName);
}
public int getAttributeCount()
{
return attributes.getAttributeCount();
}
public Enumeration getAttributeNames()
{
return attributes.getAttributeNames();
}
public boolean isDefined(Object attrName)
{
return attributes.isDefined(attrName);
}
public boolean isEqual(AttributeSet attr)
{
return attributes.isEqual(attr);
}
public void removeAttribute(Object name)
{
attributes = StyleContext.this.removeAttribute(attributes, name);
fireStateChanged();
}
public void removeAttributes(AttributeSet attrs)
{
attributes = StyleContext.this.removeAttributes(attributes, attrs);
fireStateChanged();
}
public void removeAttributes(Enumeration names)
{
attributes = StyleContext.this.removeAttributes(attributes, names);
fireStateChanged();
}
public AttributeSet getResolveParent()
{
return attributes.getResolveParent();
}
public void setResolveParent(AttributeSet parent)
{
attributes = StyleContext.this.addAttribute(attributes, ResolveAttribute, parent);
fireStateChanged();
}
public String toString()
{
return ("[NamedStyle: name=" + name + ", attrs=" + attributes.toString() + "]");
}
}
public class SmallAttributeSet
implements AttributeSet
{
final Object [] attrs;
public SmallAttributeSet(AttributeSet a)
{
if (a == null)
attrs = new Object[0];
else
{
int n = a.getAttributeCount();
int i = 0;
attrs = new Object[n * 2];
Enumeration e = a.getAttributeNames();
while (e.hasMoreElements())
{
Object name = e.nextElement();
attrs[i++] = name;
attrs[i++] = a.getAttribute(name);
}
}
}
public SmallAttributeSet(Object [] a)
{
if (a == null)
attrs = new Object[0];
else
{
attrs = new Object[a.length];
System.arraycopy(a, 0, attrs, 0, a.length);
}
}
public Object clone()
{
return new SmallAttributeSet(this.attrs);
}
public boolean containsAttribute(Object name, Object value)
{
for (int i = 0; i < attrs.length; i += 2)
{
if (attrs[i].equals(name) &&
attrs[i+1].equals(value))
return true;
}
return false;
}
public boolean containsAttributes(AttributeSet a)
{
Enumeration e = a.getAttributeNames();
while (e.hasMoreElements())
{
Object name = e.nextElement();
Object val = a.getAttribute(name);
if (!containsAttribute(name, val))
return false;
}
return true;
}
public AttributeSet copyAttributes()
{
return (AttributeSet) clone();
}
public boolean equals(Object obj)
{
return
(obj instanceof SmallAttributeSet)
&& this.isEqual((AttributeSet)obj);
}
public Object getAttribute(Object key)
{
for (int i = 0; i < attrs.length; i += 2)
{
if (attrs[i].equals(key))
return attrs[i+1];
}
Object p = getResolveParent();
if (p != null && p instanceof AttributeSet)
return (((AttributeSet)p).getAttribute(key));
return null;
}
public int getAttributeCount()
{
return attrs.length / 2;
}
public Enumeration getAttributeNames()
{
return new Enumeration()
{
int i = 0;
public boolean hasMoreElements()
{
return i < attrs.length;
}
public Object nextElement()
{
i += 2;
return attrs[i-2];
}
};
}
public AttributeSet getResolveParent()
{
return (AttributeSet) getAttribute(ResolveAttribute);
}
public int hashCode()
{
return java.util.Arrays.asList(attrs).hashCode();
}
public boolean isDefined(Object key)
{
for (int i = 0; i < attrs.length; i += 2)
{
if (attrs[i].equals(key))
return true;
}
return false;
}
public boolean isEqual(AttributeSet attr)
{
return attr != null
&& attr.containsAttributes(this)
&& this.containsAttributes(attr);
}
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append("[StyleContext.SmallattributeSet:");
for (int i = 0; i < attrs.length; ++i)
{
sb.append(" (");
sb.append(attrs[i].toString());
sb.append("=");
sb.append(attrs[i+1].toString());
sb.append(")");
}
sb.append("]");
return sb.toString();
}
}
// FIXME: official javadocs suggest that these might be more usefully
// implemented using a WeakHashMap, but not sure if that works most
// places or whether it really matters anyways.
//
// FIXME: also not sure if these tables ought to be static (singletons),
// shared across all StyleContexts. I think so, but it's not clear in
// docs. revert to non-shared if you think it matters.
public static final String DEFAULT_STYLE = "default";
static Hashtable sharedAttributeSets = new Hashtable();
static Hashtable sharedFonts = new Hashtable();
static StyleContext defaultStyleContext = new StyleContext();
static final int compressionThreshold = 9;
EventListenerList listenerList;
Hashtable styleTable;
public StyleContext()
{
listenerList = new EventListenerList();
styleTable = new Hashtable();
}
protected SmallAttributeSet createSmallAttributeSet(AttributeSet a)
{
return new SmallAttributeSet(a);
}
protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
{
return new SimpleAttributeSet(a);
}
public void addChangeListener(ChangeListener listener)
{
listenerList.add(ChangeListener.class, listener);
}
public void removeChangeListener(ChangeListener listener)
{
listenerList.remove(ChangeListener.class, listener);
}
public ChangeListener[] getChangeListeners()
{
return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
}
public Style addStyle(String name, Style parent)
{
Style newStyle = new NamedStyle(name, parent);
if (name != null)
styleTable.put(name, newStyle);
return newStyle;
}
public void removeStyle(String name)
{
styleTable.remove(name);
}
public Style getStyle(String name)
{
return (Style) styleTable.get(name);
}
public Enumeration getStyleNames()
{
return styleTable.keys();
}
//
// StyleContexts only understand the "simple" model of fonts present in
// pre-java2d systems: fonts are a family name, a size (integral number
// of points), and a mask of style parameters (plain, bold, italic, or
// bold|italic). We have an inner class here called SimpleFontSpec which
// holds such triples.
//
// A SimpleFontSpec can be built for *any* AttributeSet because the size,
// family, and style keys in an AttributeSet have default values (defined
// over in StyleConstants).
//
// We keep a static cache mapping SimpleFontSpecs to java.awt.Fonts, so
// that we reuse Fonts between styles and style contexts.
//
private static class SimpleFontSpec
{
String family;
int style;
int size;
public SimpleFontSpec(String family,
int style,
int size)
{
this.family = family;
this.style = style;
this.size = size;
}
public boolean equals(Object obj)
{
return (obj != null)
&& (obj instanceof SimpleFontSpec)
&& (((SimpleFontSpec)obj).family.equals(this.family))
&& (((SimpleFontSpec)obj).style == this.style)
&& (((SimpleFontSpec)obj).size == this.size);
}
public int hashCode()
{
return family.hashCode() + style + size;
}
}
public Font getFont(AttributeSet attr)
{
String family = StyleConstants.getFontFamily(attr);
int style = Font.PLAIN;
if (StyleConstants.isBold(attr))
style += Font.BOLD;
if (StyleConstants.isItalic(attr))
style += Font.ITALIC;
int size = StyleConstants.getFontSize(attr);
return getFont(family, style, size);
}
public Font getFont(String family, int style, int size)
{
SimpleFontSpec spec = new SimpleFontSpec(family, style, size);
if (sharedFonts.containsKey(spec))
return (Font) sharedFonts.get(spec);
else
{
Font tmp = new Font(family, style, size);
sharedFonts.put(spec, tmp);
return tmp;
}
}
public FontMetrics getFontMetrics(Font f)
{
return Toolkit.getDefaultToolkit().getFontMetrics(f);
}
public Color getForeground(AttributeSet a)
{
return StyleConstants.getForeground(a);
}
public Color getBackground(AttributeSet a)
{
return StyleConstants.getBackground(a);
}
protected int getCompressionThreshold()
{
return compressionThreshold;
}
public static StyleContext getDefaultStyleContext()
{
return defaultStyleContext;
}
public AttributeSet addAttribute(AttributeSet old, Object name, Object value)
{
if (old instanceof MutableAttributeSet)
{
((MutableAttributeSet)old).addAttribute(name, value);
return old;
}
else
{
MutableAttributeSet mutable = createLargeAttributeSet(old);
mutable.addAttribute(name, value);
if (mutable.getAttributeCount() >= getCompressionThreshold())
return mutable;
else
{
SmallAttributeSet small = createSmallAttributeSet(mutable);
if (sharedAttributeSets.containsKey(small))
small = (SmallAttributeSet) sharedAttributeSets.get(small);
else
sharedAttributeSets.put(small,small);
return small;
}
}
}
public AttributeSet addAttributes(AttributeSet old, AttributeSet attributes)
{
if (old instanceof MutableAttributeSet)
{
((MutableAttributeSet)old).addAttributes(attributes);
return old;
}
else
{
MutableAttributeSet mutable = createLargeAttributeSet(old);
mutable.addAttributes(attributes);
if (mutable.getAttributeCount() >= getCompressionThreshold())
return mutable;
else
{
SmallAttributeSet small = createSmallAttributeSet(mutable);
if (sharedAttributeSets.containsKey(small))
small = (SmallAttributeSet) sharedAttributeSets.get(small);
else
sharedAttributeSets.put(small,small);
return small;
}
}
}
public AttributeSet getEmptySet()
{
AttributeSet e = createSmallAttributeSet(null);
if (sharedAttributeSets.containsKey(e))
e = (AttributeSet) sharedAttributeSets.get(e);
else
sharedAttributeSets.put(e, e);
return e;
}
public void reclaim(AttributeSet attributes)
{
if (sharedAttributeSets.containsKey(attributes))
sharedAttributeSets.remove(attributes);
}
public AttributeSet removeAttribute(AttributeSet old, Object name)
{
if (old instanceof MutableAttributeSet)
{
((MutableAttributeSet)old).removeAttribute(name);
if (old.getAttributeCount() < getCompressionThreshold())
{
SmallAttributeSet small = createSmallAttributeSet(old);
if (!sharedAttributeSets.containsKey(small))
sharedAttributeSets.put(small,small);
old = (AttributeSet) sharedAttributeSets.get(small);
}
return old;
}
else
{
MutableAttributeSet mutable = createLargeAttributeSet(old);
mutable.removeAttribute(name);
SmallAttributeSet small = createSmallAttributeSet(mutable);
if (sharedAttributeSets.containsKey(small))
small = (SmallAttributeSet) sharedAttributeSets.get(small);
else
sharedAttributeSets.put(small,small);
return small;
}
}
public AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes)
{
return removeAttributes(old, attributes.getAttributeNames());
}
public AttributeSet removeAttributes(AttributeSet old, Enumeration names)
{
if (old instanceof MutableAttributeSet)
{
((MutableAttributeSet)old).removeAttributes(names);
if (old.getAttributeCount() < getCompressionThreshold())
{
SmallAttributeSet small = createSmallAttributeSet(old);
if (!sharedAttributeSets.containsKey(small))
sharedAttributeSets.put(small,small);
old = (AttributeSet) sharedAttributeSets.get(small);
}
return old;
}
else
{
MutableAttributeSet mutable = createLargeAttributeSet(old);
mutable.removeAttributes(names);
SmallAttributeSet small = createSmallAttributeSet(mutable);
if (sharedAttributeSets.containsKey(small))
small = (SmallAttributeSet) sharedAttributeSets.get(small);
else
sharedAttributeSets.put(small,small);
return small;
}
}
// FIXME: there's some sort of quasi-serialization stuff in here which I
// have left incomplete; I'm not sure I understand the intent properly.
public static Object getStaticAttribute(Object key)
{
throw new InternalError("not implemented");
}
public static Object getStaticAttributeKey(Object key)
{
throw new InternalError("not implemented");
}
public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a)
throws ClassNotFoundException, IOException
{
throw new InternalError("not implemented");
}
public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
throws IOException
{
throw new InternalError("not implemented");
}
public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
throws ClassNotFoundException, IOException
{
throw new InternalError("not implemented");
}
public void writeAttributes(ObjectOutputStream out, AttributeSet a)
throws IOException
{
throw new InternalError("not implemented");
}
}

View File

@ -0,0 +1,102 @@
/* TabSet.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.text;
import java.io.Serializable;
public class TabSet implements Serializable
{
TabStop[] tabs;
public TabSet(TabStop[] t)
{
tabs = t;
}
public TabStop getTab(int i)
{
return tabs[i];
}
public TabStop getTabAfter(float location)
{
int idx = getTabIndexAfter(location);
if (idx == -1)
return null;
else
return tabs[idx];
}
public int getTabCount()
{
return tabs.length;
}
public int getTabIndex(TabStop tab)
{
for (int i = 0; i < tabs.length; ++i)
if (tabs[i] == tab)
return i;
return -1;
}
public int getTabIndexAfter(float location)
{
int idx = -1;
for (int i = 0; i < tabs.length; ++i)
{
if (location < tabs[i].getPosition())
idx = i;
}
return idx;
}
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append("[");
for (int i = 0; i < tabs.length; ++i)
{
if (i != 0)
sb.append(" - ");
sb.append(tabs[i].toString());
}
sb.append("]");
return sb.toString();
}
}

View File

@ -0,0 +1,133 @@
/* TabSet.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.text;
import java.io.Serializable;
public class TabStop implements Serializable
{
public static final int ALIGN_LEFT = 0;
public static final int ALIGN_RIGHT = 1;
public static final int ALIGN_CENTER = 2;
public static final int ALIGN_DECIMAL = 4;
public static final int ALIGN_BAR = 5;
public static final int LEAD_NONE = 0;
public static final int LEAD_DOTS = 1;
public static final int LEAD_HYPHENS = 2;
public static final int LEAD_UNDERLINE = 3;
public static final int LEAD_THICKLINE = 4;
public static final int LEAD_EQUALS = 5;
float pos;
int align;
int leader;
public TabStop(float pos)
{
this(pos, ALIGN_LEFT, LEAD_NONE);
}
public TabStop(float pos, int align, int leader)
{
this.pos = pos;
this.align = align;
this.leader = leader;
}
public boolean equals(Object other)
{
return (other != null)
&& (other instanceof TabStop)
&& (((TabStop)other).getPosition() == this.getPosition())
&& (((TabStop)other).getLeader() == this.getLeader())
&& (((TabStop)other).getAlignment() == this.getAlignment());
}
public int getAlignment()
{
return align;
}
public int getLeader()
{
return leader;
}
public float getPosition()
{
return pos;
}
public int hashCode()
{
return (int) pos + (int) leader + (int) align;
}
public String toString()
{
String prefix = "";
switch (align)
{
case ALIGN_LEFT:
prefix = "left ";
break;
case ALIGN_RIGHT:
prefix = "right ";
break;
case ALIGN_CENTER:
prefix = "center ";
break;
case ALIGN_DECIMAL:
prefix = "decimal ";
break;
case ALIGN_BAR:
prefix = "bar ";
break;
default:
break;
}
return (prefix + "tab @" + pos + ((leader == LEAD_NONE) ? "" : "(w/leaders)"));
}
}

View File

@ -0,0 +1,182 @@
/* Utilities.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.text;
import java.awt.FontMetrics;
import java.awt.Graphics;
/**
* A set of utilities to deal with text. This is used by several other classes
* inside this package.
*
* @author Roman Kennke <roman@ontographics.com>
*/
public class Utilities
{
/**
* The length of the char buffer that holds the characters to be drawn.
*/
private static final int BUF_LENGTH = 64;
/**
* Creates a new <code>Utilities</code> object.
*/
public Utilities()
{
// Nothing to be done here.
}
/**
* Draws the given text segment. Contained tabs and newline characters
* are taken into account. Tabs are expanded using the
* specified {@link TabExpander}.
*
* @param s the text fragment to be drawn.
* @param x the x position for drawing.
* @param y the y position for drawing.
* @param g the {@link Graphics} context for drawing.
* @param e the {@link TabExpander} which specifies the Tab-expanding
* technique.
* @param startOffset starting offset in the text.
* @return the x coordinate at the end of the drawn text.
*/
public static final int drawTabbedText(Segment s, int x, int y, Graphics g,
TabExpander e, int startOffset)
{
// This buffers the chars to be drawn.
char[] buffer = s.array;
// The current x and y pixel coordinates.
int pixelX = x;
int pixelY = y;
// The font metrics of the current selected font.
FontMetrics metrics = g.getFontMetrics();
int ascent = metrics.getAscent();
for (int offset = s.offset; offset < (s.offset + s.count); ++offset)
{
switch (buffer[offset])
{
case '\t':
// In case we have a tab, we just 'jump' over the tab.
// When we have no tab expander we just use the width of 'm'.
if (e != null)
pixelX = (int) e.nextTabStop((float) pixelX,
startOffset + offset - s.offset);
else
pixelX += metrics.charWidth(' ');
break;
case '\n':
// In case we have a newline, we must draw
// the buffer and jump on the next line.
g.drawChars(buffer, offset, 1, pixelX, y);
pixelY += metrics.getHeight();
pixelX = x;
break;
default:
// Here we draw the char.
g.drawChars(buffer, offset, 1, pixelX, pixelY + ascent);
pixelX += metrics.charWidth(buffer[offset]);
break;
}
}
return pixelX;
}
/**
* Determines the width, that the given text <code>s</code> would take
* if it was printed with the given {@link java.awt.FontMetrics} on the
* specified screen position.
* @param s the text fragment
* @param metrics the font metrics of the font to be used
* @param x the x coordinate of the point at which drawing should be done
* @param e the {@link TabExpander} to be used
* @param startOffset the index in <code>s</code> where to start
* @returns the width of the given text s. This takes tabs and newlines
* into account.
*/
public static final int getTabbedTextWidth(Segment s, FontMetrics metrics,
int x, TabExpander e,
int startOffset)
{
// This buffers the chars to be drawn.
char[] buffer = s.array;
// The current x coordinate.
int pixelX = x;
// The current maximum width.
int maxWidth = 0;
for (int offset = s.offset; offset < (s.offset + s.count); ++offset)
{
switch (buffer[offset])
{
case '\t':
// In case we have a tab, we just 'jump' over the tab.
// When we have no tab expander we just use the width of 'm'.
if (e != null)
pixelX = (int) e.nextTabStop((float) pixelX,
startOffset + offset - s.offset);
else
pixelX += metrics.charWidth(' ');
break;
case '\n':
// In case we have a newline, we must 'draw'
// the buffer and jump on the next line.
pixelX += metrics.charWidth(buffer[offset]);
maxWidth = Math.max(maxWidth, pixelX - x);
pixelX = x;
break;
default:
// Here we draw the char.
pixelX += metrics.charWidth(buffer[offset]);
break;
}
}
// Take the last line into account.
maxWidth = Math.max(maxWidth, pixelX - x);
return maxWidth;
}
}

View File

@ -0,0 +1,68 @@
/* Native implementation of functions in GThreadNativeMethodRunner
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
#include "gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h"
#include "gthread-jni.h"
/*
* Class: GThreadNativeMethodRunner
* Method: nativeRun
* Signature: (J)V
*
* Purpose: Run the C function whose function pointer is
*
*/
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_nativeRun(JNIEnv *gdk_env, jobject lcl_obj,
jlong funcAddr, jlong funcArg)
{
/* Convert the function's address back into a pointer to a C function. */
void *(*funcPtr)(void *) = (void *(*)(void *)) funcAddr;
/* We do not need to worry about the return value from funcPtr(); it's
just thrown away. That is part of the g_threads spec, so no reason
to worry about returning it. */
(void) funcPtr((void *) funcArg);
/* Fall off the end and terminate the thread of control. */
}
/* Local Variables: */
/* c-file-style: "gnu" */
/* End: */