I can't find a way to transform the code when replacing the deprecated functionhandleEvent withprocessEvent. can anyone help?
how to get x, y and the id of the event on processEvent?
here is my function:
public boolean handleEvent(Event evt) {
if (evt.target == this) {
// move floatting text zone
if (dragingTextZone == true) {
this.posStr.x = evt.x;
this.posStr.y = evt.y;
repaint(this.posStr.x,
this.posStr.y,
1000,
(int) (_imageViewer.getCurrent_font().getSize() * _imageViewer.getScalefactor()));
if (evt.id == Event.MOUSE_DOWN) {
dragingTextZone = false;
addTextToPicture();
}
}
if (evt.id == Event.MOUSE_DRAG) {
if (dragitem.isDragging()) {
repaint(dragitem.getX(),
dragitem.getY(),
dragitem.getWidth(),
dragitem.getHeight());
dragitem.drag(evt.x, evt.y);
repaint(dragitem.getX(),
dragitem.getY(),
dragitem.getWidth(),
dragitem.getHeight());
}
}
else {
if (evt.id == Event.MOUSE_UP) {
// setting crop zone
if (dragingCropZone || dragingMask) {
endDrag(evt);
}
else if (dragingLine) {
addLineToPicture();
endDrag(evt);
}
}
if (evt.id == Event.MOUSE_DOWN) {
if (getEditMode() == EDTMODE_ALL) {
if (evt.modifiers == Event.CTRL_MASK) {
startDragHighLight(evt);
}
else if (evt.modifiers == Event.ALT_MASK) {
startDragLine(evt);
}
else {
if (clickedOnFocusedItem(evt)) {
startDragMask(evt);
}
}
}
}
}
}
return super.handleEvent(evt); // This passess the mouse click back up to Applet
}
Thank you,
Rather than a single Event class that includes everything, the new (relatively speaking - it's been around since Java 1.1) AWTEvent approach is to have different subclasses of AWTEvent for different purposes. In your case it's the MouseEvent subclass you're interested in, so you would need to call enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK) to enable handling of the relevant events, then override processMouseEvent and processMouseMotionEvent to do the handling.
But the preferred way to handle events is not to override the process* methods but rather to register separate listener objects. In your case you would create another class (possibly an inner class inside your main one) which is a subclass of MouseAdapter, override the relevant event hook methods in that, then register an instance of the adapter class by calling both addMouseListener and addMouseMotionListener on the main component.
There is extensive documentation on the Oracle website (and elsewhere) on how to implement event handling in an AWT or Swing application.
Related
#EventHandler
public void playerInteraction(PlayerInteractEvent event)
{
Action action = event.getAction();
Player player = event.getPlayer();
Block block = event.getClickedBlock();
if (action.equals(Action.RIGHT_CLICK_BLOCK))
{
if (block.getType().equals(Material.NETHER_WART_BLOCK))
{
player.setHealth(player.getHealth() -1);
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_HURT, 10, 1);
}
else if (block.getType().equals(Material.DIAMOND_BLOCK))
{
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 1000, 2));
player.playSound(player.getLocation(), Sound.ENTITY_SPLASH_POTION_BREAK, 10, 1);
}
else if(block.getType().equals(Material.EMERALD_BLOCK))
{
if (player.getHealth() != 20)
{
player.setHealth(player.getHealth() + 1);
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 10, 1);;
}
if (player.getHealth() == 20)
{
player.sendMessage(ChatColor.DARK_RED + "You are already at full health!");
}
}
}
}
For some reason, all of these things happen twice whenever I right click the designated blocks. Anyone know why? I have posted the entire method, it's a player interaction event.
Thanks :)
First of all, make sure yo haven't registered the Listener class containing the event handler twice.
If that's not the case, according to this thread on the spigot forums, since Mojang added the left hand slot to Minecraft some events like PlayerInteractEvent or InventoryClickEvent will be called twice (once for each hand).
One possible fix is to "disable" the left hand on the event handler:
#EventHandler
public void onPlayerInteraction(PlayerInteractEvent event) {
if(event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getHand() == EquipmentSlot.HAND) {
//Do something once
}
}
If you require that both hands could be used to trigger the event you could do the following:
First time the code gets executed you add the player to a list.
Before executing the code you check if the player is in the list. If it's in the list it means the code was executed once so you can skip it.
Schedule a task to remove the player from the list some ticks later.
The code could be as follows:
public class Foo implements Listener {
//An instance of the main plugin class
private MainClass plugin;
private List<UUID> playerBlacklist = new ArrayList<>();
#EventHandler
public void onPlayerInteractEvent(PlayerInteractEvent event) {
if(playerBlacklist.contains(event.getPlayer().getUniqueId)) {
return;
} else {
blacklistPlayer(event.getPlayer());
}
//Do something
}
private void blacklistPlayer(UUID uuid) {
playerBlacklist.add(uuid);
BukkitRunnable runnable = new BukkitRunnable(){
#Override
public void run() {
playerBlacklist.remove(uuid);
}
}
runnable.runTaskLaterAsynchronously(plugin, 5L);
}
}
Let me know if this solved your issue.
I'm having a problem with my Java code.
I need to execute my doSomething() method, which includes code that manage also global variables. The problem is that the method is invoked twice (both mouseEvent and focusEvent of my JTable are fired at the same time).
How can I execute the doSomething() method only once at a time, in a sort of mutual exclusion ?
Thanks.
addMouseListener (new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
doSomething();
}
});
addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent e){
doSomething();
}
});
JTable cells contains String with length 1 or 2.
I need to apply a setValue method (or delete the String), in the exact moment the user stops the cell editing or he writes a 2 character String.
With those listeners I know the exact time to do the setValue or to inform the user that the first character he wrote doesn't exist. So in that way I wanted to block the user's action.
In other words, I need to control the user input in order to do a setValue or delete it. FocusLost tells me when the user clicks outside the JTable Component.
MouseClicked tells me when the user clicks in the JTable Component.
When mouseClicked is invoked and the JOptionPane appears, the cell automatically lose the focus, and so also the focusLost is invoked.
public void doSomething () {
// inEdit and tableCellEdited are the global variables
if ( inEdit && tableCellEdited != null ) {
String temp = "" + tableCellEdited.getDay();
String s = tableCellEdited.getValRenderer().trim();
if (s.length() > 2) s = s.substring(4);
if ( !s.trim().isEmpty() ) {
JOptionPane.showMessageDialog(getParent(),
"Code doesn't exist" , "Error: Code doesn't exist",JOptionPane.WARNING_MESSAGE);
tableCellEdited.setRendererValue(getUltimaGG(), false);
}
else {
tableCellEdited.setRendererValue(s, false);
setValueAt(tableCellEdited, getRowFromMat(tableCellEdited.getMat()), Integer.parseInt(temp.substring(6, 8)) );
}
clearProgrammazioneDueCaratteri();
}
}
repaint();
}
I have spent almost three days trying to do a simple enable / disable of Actions in the netbeans plaform, something that I though was going to be simple, and should be a common feature is more complex than I thought.
At the begging I tried to see if there was an setEnable() method on the default actions generated and to my surprise there is not. Then I started looking into that and I found that most common method to do it was setting a conditionally enabled action (which depends on a Cookie class), So I figured out how to add a fake class to the Lookup so it gets enabled and disabled, I did it the following way. To test it out I added the following code to another action which should enable or disable the second one.
private final PlottingStarted plottingStarted = new PlottingStarted();
#Override
public void actionPerformed(ActionEvent e) {
// TODO implement action body
if (Lookup.getDefault().lookup(PlottingStarted.class) == null) {
ic.add(plottingStarted);
}else{
ic.remove(plottingStarted);
}
So PlottingStarted is a fake object I created which only purpose is being in the lookup to disable or enable the action.
For some reason it did not do anything at all an the Action was always disabled. I tried many things and finally I gave up.
Then I tried a different approach and was using AbstractActions which do have the setEnabled() ability.
To retrieve the action I based myself on one the Geertjan blogs and I created the following method
public Action findAction(String actionName) {
FileObject myActionsFolder = FileUtil.getConfigFile("Actions/RealTimeViewer");
if (myActionsFolder != null){
FileObject[] myActionsFolderKids = myActionsFolder.getChildren();
for (FileObject fileObject : myActionsFolderKids) {
//Probably want to make this more robust,
//but the point is that here we find a particular Action:
if (fileObject.getName().contains(actionName)) {
try {
DataObject dob = DataObject.find(fileObject);
InstanceCookie ic = dob.getLookup().lookup(InstanceCookie.class);
if (ic != null) {
Object instance = ic.instanceCreate();
if (instance instanceof Action) {
Action a = (Action) instance;
return a;
}
}
} catch (Exception e) {
ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
return null;
}
}
}
}
return null;
}
This method worked perfectly and I was able to retrieve the action and call its setEnabled() method. Unfortunately no matter why I did the Action was always enabled.
Reading some literature I found that I should add the following to the registration of the action "lazy = false" and finally I was able to enable and disable the Action... But off course the default registration is lost and I have no Icons and Names.
Now I decided to post again because I cannot believe that it need to be that complex, there must be a way to do it easier. The only thing I need is to have a PLAY / STOP functionality, when PLAY is enabled STOP is disabled and vice-versa.
I have not done this myself but it seems to be covered in Chapter 5.1.2.1 "Complex Enablement" of the book "Netbeans Platform for Beginners". https://leanpub.com/nbp4beginners
The book is not free but the corresponding code sample is available on
github. https://github.com/walternyland/nbp4beginners/tree/master/chapters/ch05/5.1.2.1 He extends AbstractAction overrides the resultChanged method and uses super.setEnabled().
#ActionID(id = "org.carsales.evaluator.EvaluateCarAction1", category = "Car")
#ActionRegistration(displayName = "not-used", lazy = false)
public class EvaluateCarAction extends AbstractAction
implements ContextAwareAction, LookupListener {
// ...
#Override
public void resultChanged(LookupEvent le) {
//Optionally, check if the property is set to the value you're interested in
//prior to enabling the Action.
super.setEnabled(result.allInstances().size() > 0);
}
Thanks to everybody for your responses. I finally got it to work by extending AbstractAction, it seems that even if you register "lazy = false" some of the registration is still being done by the platform and you just need some minor tweaking in the Action constructor. The final result was
#ActionID(
category = "RealTimeViewer",
id = "main.java.com.graph.actions.StopPlotting"
)
#ActionRegistration(
//iconBase = "main/java/com/graph/images/stop-plotting-24x24.png",
displayName = "#CTL_StopPlotting",
lazy = false
)
#ActionReference(path = "Toolbars/RealTimeViewer", position = 600)
#Messages("CTL_StopPlotting=Stop Plotting")
public final class StopPlotting extends AbstractAction{
private static final String ICON = "main/java/com/dacsys/cna/core/graph/images/stop-plotting-24x24.png";
public StopPlotting() {
putValue(SMALL_ICON, ImageUtilities.loadImageIcon(ICON, false));
putValue(NAME, Bundle.CTL_StopPlotting());
this.setEnabled(false);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO implement action body
Action a = new ActionsHelper().findAction("StartPlotting");
if (a != null){
if (a != null){
if (a.isEnabled()){
a.setEnabled(false);
this.setEnabled(true);
}else{
a.setEnabled(true);
this.setEnabled(false);
}
}
}
}
}
I am having an issue where calling JComboBox.setSelectedIndex(0) causes
my program to crash. Any help would be greatly appreciated!!
On itemStateChanged() starts a new Thread to handle UpdateAllForms.
UpdateAllForms calls updateComboModel() which Queries an SQL Database to update the ComboBoxModel and adds an additional option 'Select...'
This all works fine, however if i add JComboBox.setSelectedIndex(0) the
program crashes with no exception etc. I assume the issue is with threading?
itemStateChanged() Method:
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.DESELECTED) {
Runnable updateRunnable = new UpdateAllForms(e.getSource());
new Thread(updateRunnable).start();
}
}
UpdateAllForms Class:
// <<=== UpdateAllForms Class ===>>
// Only Updates Forms below the Current Form
// Must be ran as a Separate Thread due to swing concurrency
// ==============================================================================
public class UpdateAllForms implements Runnable {
Object source = null;
public UpdateAllForms(Object source) {
this.source = source;
}
#Override
public void run() {
// TODO Auto-generated method stub
boolean shouldUpdate = false;
Logger.write("PropConfDialog.updateAllForms");
// Loop through Forms
for (int formCount = 0; formCount < dataInputForms.get(1).size(); formCount++) {
Component curForm = dataInputForms.get(1).get(formCount);
// Update Forms after current form
if (shouldUpdate) {
if (curForm instanceof JSQLComboPanel) {
JSQLComboPanel panel = (JSQLComboPanel) curForm;
// Resets the where String
panel.setWhereString(getInputString(panel.getInputID()));
panel.updateComboModel();
shouldUpdate = true;
continue;
} else if (curForm instanceof JSQLLabelPanel) {
JSQLLabelPanel panel = (JSQLLabelPanel) curForm;
panel.setWhereString(getInputString(panel.getInputID()));
panel.updateLabel();
shouldUpdate = true;
Logger.write("LABEL CAN CARRY OUT");
continue;
}// End if/else
} // End should update
if (source == ((JSQLComboPanel) dataInputForms.get(1).get(formCount)).getComboBox()) {
shouldUpdate = true;
}// End if
}// End Loop
}// End updateAllCombos()
}// End UpdateAllForms Class
JSQLComboPanel Class - updateComboModel Method !!THIS IS THE ISSUE!!! if I call
combo.setSelectedIndex(0) in this method the program crashes.
public void updateComboModel(){
if(comboType == TYPE_DRIVEN_COMBO){
ArrayList values = SQLTools.getColValues(lkTable, lkNameCol);
combo.setModel(new DefaultComboBoxModel(values.toArray(new String[values.size()])));
}else if(comboType == TYPE_WHERE_COMBO){
ArrayList values = SQLTools.executeJoin(fkTable, fkIDCol, fkNameCol, lkTable, lkIDCol, lkNameCol, whereString);
combo.setModel(new DefaultComboBoxModel(values.toArray(new String[values.size()])));
}else if(comboType == TYPE_WHERE_LINKED_COMBO){
ArrayList values = SQLTools.executeLinkTableJoin(fkTable, fkIDCol, fkNameCol, linkTable, fkIDCol, lkIDCol, lkTable, lkIDCol, lkNameCol,whereString);
combo.setModel(new DefaultComboBoxModel(values.toArray(new String[values.size()])));
}//End if/else
combo.insertItemAt("Select...", 0);
//combo.setSelectedIndex(0);
combo.repaint();
}//End updateComboModel()
If anybody can shed any light, that would be fantastic! I am fairly new to Java especially Threading!
Thanks again
Tim
The problem is (almost certainly) related to the fact that you are modifying the state of Swing Components on the wrong thread.
The general rule is:
Code that depends on or modifies the state of a Swing Component should be executed on the Event Dispatch Thread.
A violation of this rule may sometimes be hard to detect - particularly, when only a model is modified, which does not necessarily have a connection to a GUI component!
However, in your case, the main problem is more obvious, because there is (at least) the problematic call
combo.setModel(new DefaultComboBoxModel(values.toArray(new String[values.size()])));
which happens on an own thread, and modifies the Swing component directly.
As suggested in the comments, you should definitiely consider using a SwingWorker. More details about the SwingWorker (and threading in Swing in general) can be found in the article about Concurrency In Swing
A quick workaround for your problem could be the following:
...
// Remove this line
//combo.setModel(new DefaultComboBoxModel(values.toArray(new String[values.size()])));
// Replace it with this line
setModelOnEDT(combo, new DefaultComboBoxModel(values.toArray(new String[values.size()]));
and create a method like this:
private static void setModelOnEDT(
final JComboBox comboBox, final ComboBoxModel model)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
comboBox.setModel(model);
}
});
}
This is certainly not the prettiest solution, but the simplest, until you modify the code to use a SwingWorker.
I found this blocking GlassPane class on the web and I'm curious to know if some of you see any problem with it.
public final class BlockingGlassPane extends JComponent implements AWTEventListener {
// Events will be consumed for this window.
private Window parentWindow;
// Focus will be returned to this component.
private Component lastFocusOwner;
private final Toolkit toolkit;
public BlockingGlassPane() {
super();
setOpaque(false);
addMouseListener(new MouseAdapter() {
});
addKeyListener(new KeyAdapter() {
});
setInputVerifier(new InputVerifier() {
#Override
public boolean verify(JComponent anInput) {
return false;
}
});
toolkit = Toolkit.getDefaultToolkit();
}
#Override
public void setVisible(boolean b) {
if (b) {
if (parentWindow == null) {
parentWindow = SwingUtilities.windowForComponent(this);
}
Component focusOwner = parentWindow.getFocusOwner();
if (focusOwner != this) {
lastFocusOwner = focusOwner;
}
toolkit.addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
toolkit.addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK);
requestFocus();
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
} else {
toolkit.removeAWTEventListener(this);
if (lastFocusOwner != null) {
lastFocusOwner.requestFocus();
lastFocusOwner = null;
}
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
super.setVisible(b);
}
#SuppressWarnings("unchecked")
public void eventDispatched(AWTEvent e) {
Object source = e.getSource();
if (e instanceof EventObject && source instanceof Component) {
Component src = (Component) source;
EventObject ev = e;
if (SwingUtilities.windowForComponent(src) == parentWindow) {
try {
Class[] cls = {};
Object[] args = {};
ev.getClass().getMethod("consume", cls).invoke(ev, args);
} catch (Exception ex) {
// ex.printStackTrace();
}
}
}
}
Just at a glance, I see several problems here, mostly in and around the eventDispatched() method.
First, why are you implementing AWTEventListener at all, since you never add this object to anything as an AWTEventListener? Did you mean to add this object to itself as an event listener? Are you adding it as an event listener somewhere else in code that isn't shown here?
Second, why do you test e instanceof EventObject? I cut-and-pasted your code into Eclipse, which immediately warned me that all AWTEvent objects are instances of EventObject. So, you can get rid of that test - It will always be true.
Third, why on earth are you resorting to reflection? It looks as if you are trying to use a Swing-only method on AWT events that don't have it. That approach won't work - Trying to reflectively call a nonexistent method will just throw an exception, which this code will silently catch and ignore.
Finally, why are you reinventing the wheel? Some quick Googling reveals some simpler examples and some more complicated examples that you could use as a starting point for your work and which would likely get you much closer to what you really want here.