blob: 673cd8d1e39eb649b74a8094e4d846c42978ab94 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.core.output2;
import java.awt.*;
/**
* An event type which carries data about an operation performed on an
* instance of NbIO which an interested view must respond to on the
* event queue.
* <p>
* While this is an unusual approach, it is also using the event queue in
* exactly the way event queues are designed to be used. It accomplishes
* complete decoupling of the IO implementation from the view implementation -
* the IO does not need to know anything about what component is rendering
* it, it just posts relevant events onto the event queue.
* <p>
* Unfortunately, it is impossible to use an AWTEventListener to get notification
* of custom event types (appears that it once was, and was optimized out in
* the biggest if/then clause in history - see Toolkit). So we have the
* dispatch() method.
* <p>
* While all this could be done with SwingUtilities.invokeLater() and runnables,
* this approach works well and is somewhat more lightweight, so I see no need
* to change it.
* <p>
* Should someone want to make this package capable of supporting multiple
* output windows, for some reason, the only thing necessary to do is to
* add a registry of weakly referenced OutputContainers and iterate them all
* in <code>dispatch()</code> - the only static tie to the rest of the
* universe is the DEFAULT field of Controller.
*
* @author Tim Boudreau
*/
final class IOEvent extends AWTEvent implements ActiveEvent {
static final int IO_EVENT_MASK = 0xF0000;
/**
* Command instructing the controller to create a new view for the IO.
* If getValue() returns true, it will try to find an existing closed tab
* with the same name and reuse it.
*/
static final int CMD_CREATE = 0;
/**
* Command to set the output visible. Output is always visible in the current
* implementation, so this command is provided for completeness but will be ignored.
*/
static final int CMD_OUTPUT_VISIBLE=1;
/**
* Set the input area visible.
*/
static final int CMD_INPUT_VISIBLE=2;
/**
* Command to set the error output visible. Error output is interleaved in the current
* implementation, so this command is provided for completeness but will be ignored.
*/
static final int CMD_ERR_VISIBLE=3;
/**
* Provided for completeness but will be ignored.
*/
static final int CMD_ERR_SEPARATED=4;
/**
* Evil and unwise but supported.
*/
static final int CMD_FOCUS_TAKEN=5;
/**
* Command indicating that the IO should become the selected tab.
*/
static final int CMD_SELECT=6;
/**
* Command indicating that the IO's tab should be closed.
*/
static final int CMD_CLOSE=7;
/**
* Command indicating that the IO has been closed for writes and the UI should performe
* any needed state changes to reflect that.
*/
static final int CMD_STREAM_CLOSED=8;
/**
* Command indicating that the output writer's reset() method has been called, and that any
* exiting output in the IO's tab should be discarded, and the closed flag reset.
*/
static final int CMD_RESET=9;
/**
* Set the toolbar actions that should be displayed.
*/
static final int CMD_SET_TOOLBAR_ACTIONS = 10;
/** set tab's icon */
static final int CMD_SET_ICON = 11;
/** set tool tip for tab */
static final int CMD_SET_TOOLTIP = 12;
/** scroll to position */
static final int CMD_SCROLL = 13;
/** set default colors */
static final int CMD_DEF_COLORS = 14;
/**
* Command to support IOSelect.select() (with "fine" control.
*/
static final int CMD_FINE_SELECT = 15;
private static final int CMD_LAST = 16;
/**
* Strings representing the event.
*/
private static final String[] CMDS = new String[] {
"CREATE", //NOI18N
"OUTPUT_VISIBLE", //NOI18N
"INPUT_VISIBLE", //NOI18N
"ERR_VISIBLE", //NOI18N
"ERR_SEPARATED", //NOI18N
"FOCUS_TAKEN", //NOI18N
"SELECT", //NOI18N
"CLOSE", //NOI18N
"STREAM_CLOSED", //NOI18N
"RESET", //NOI18N
"SET_TOOLBAR_ACTIONS", //NOI18N
"CMD_SET_ICON", //NOI18N
"CMD_SET_TOOLTIP", //NOI18N
"CMD_SCROLL", //NOI18N
"CMD_DEF_COLORS", //NOI18N
"CMD_FINE_SELECT", //NOI18N
};
/**
* Boolean value associated with this event.
*/
private boolean value = false;
/**
* Data associated with this event (used by set toolbar actions)
*/
private Object data = null;
/**
* Used by unit tests to ensure all pending events have been processed before
* continuing.
*/
static int pendingCount = 0;
/**
* Create an IOEvent with the specified source, command and boolean state for the command.
*
* @param source An instance of NbIO which something of interest has happened to; can be null
* in the case that this is CMD_DETACH, an instruction to the default instance to
* self-destruct (module uninstalled or winsys wants to install a new instance)
* @param command The ID of what has happened
* @param value The boolean state for the command to be performed
*/
IOEvent(NbIO source, int command, boolean value) {
//Null source only for destroying the default instance
super(source == null ? new Object() : source, command + IO_EVENT_MASK);
assert command >= 0 && command < CMD_LAST : "Unknown command: " + command; //NOI18N
consumed = false;
this.value = value;
pendingCount++;
}
/**
* Construct a data-bearing IOEvent with the specified source, commmand and data
*
* @param source The command source
* @param command The ID of what has happened
* @param data Data required to process this command (i.e. toolbar actions added)
*/
IOEvent(NbIO source, int command, Object data) {
this (source, command, false);
this.data = data;
}
/**
* Convenience getter for the command ID associated with this event.
* Equivalent to <code>getID() - IO_EVENT_MASK</code>.
*
* @return The command
*/
public int getCommand() {
return getID() - IO_EVENT_MASK;
}
/**
* Convenience getter for the NbIO associated with this
* command. Equivalent to <code>(NbIO) getSource()</code>
* @return
*/
public NbIO getIO() {
return getSource() instanceof NbIO ? (NbIO) getSource() : null;
}
/**
* Get a boolean value associated with the event - most use cases involve
* some thread calling boolean setters/getters on an instance of NbIO.
*
* @return The boolean state associated with this command.
*/
public boolean getValue() {
return value;
}
/**
* Get data associated with the event. This is only used for supplying
* toolbar actions.
*
* @return An object
*/
public Object getData() {
return data;
}
/**
* Determine if the event is consumed. Creation events will be.
*
* @return If the event is consumed
*/
@Override
public boolean isConsumed() {
return consumed;
}
/**
* Overridden to avoid a bit of work AWTEvent does that's not
* necessary for us.
*/
@Override
public void consume() {
consumed = true;
}
@Override
public String toString() {
return "IOEvent@" + System.identityHashCode(this) + "-" +
cmdToString(getCommand()) + " on " + getIO() +
" value= " + getValue() + " data=" + getData(); //NOI18N
}
public void dispatch() {
Controller.getDefault().eventDispatched(this);
pendingCount--;
}
public static String cmdToString (int cmd) {
return CMDS[cmd];
}
}