GeoMap isn't centring correctly - java

I have an RCP view with a GeoMap widget inside it. When the view is created, the map is centred on a position.
The problem I'm having is that when GeoMap calls getSize() it is wrong. It is returning (0,0).
I've found one method of fixing this but it required changing code in GeoMap even though I believe the problem is to do with the code in the view. If I change the setCenterPosition method for GeoMap to use the parents client area it works.
View
#PostConstruct
public void createPartControl(final Composite parent) {
Display.getDefault().asyncExec(() -> setInitialPosition());
}
private void setInitialPosition() {
widget.setCenterPosition(new PointD(longitude, latitude));
widget.redraw();
}
GeoMap
public void setCenterPosition(final Point p) {
// `parent.getClientArea()` instead of `getSize()`
final Rectangle size = getParent().getClientArea();
setMapPosition(p.x - (size.width / 2), p.y - (size.height / 2));
}
The problem with this is that I've had to change code in GeoMap to fix a problem that is likely to do with getting the size of the view. The view hasn't had the size set by the time I call to centre the map.
I've also tried adding a resize listener to the view. This wouldn't always produce the same results when getting the size of the GeoMap widget.
parent.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(final org.eclipse.swt.widgets.Event e) {
if (firstResize) {
setInitialPosition();
firstResize = false;
}
}
});
Here mentions that a resize listener should be used, and getClientArea. The problem is that GeoMap doesn't use getClientArea but I don't know if it should be.
Is this a problem with how I'm calling setCenterPosition or a bug in GeoMap?
Update
I've also tried adding a resize listener to the widget.
widget.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(final org.eclipse.swt.widgets.Event e) {
if (firstResize) {
setInitialPosition();
firstResize = false;
}
}
});
For some reason the size the widget gets is too small. It is getting a size of (615, 279) when it should be (768, 388).
By adding a button to call setCenterPosition again it gets the correct size of (768, 388).
I can fix this if I add it inside an async block but this seems more like a workaround than an actual fix.
widget.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(final org.eclipse.swt.widgets.Event e) {
if (firstResize) {
Display.getDefault().asyncExec(() -> {
setInitialPosition();
firstResize = false;
});
}
}
});

Related

GWT ScrollHandler

I have this code
#Inject
#DataField("table-col")
SimplePanel tableContainer;
#PostConstruct
public void build() {
scroll(tableContainer.getElement(), this);
tableContainer.addHandler(new ScrollHandler() {
#Override
public void onScroll(ScrollEvent scrollEvent) {
// TODO - Does not trigger
Window.alert("Scroll");
}
}, ScrollEvent.getType());
}
My question is why the tableContainer Scroll handler does now work when the similar Javascript (JSNI) handler works:
public static native void scroll(Element elem, TablePage instance) /*-{
$wnd.$( elem ).scroll(function() {
if (elem.scrollTop >= (elem.scrollHeight - elem.offsetHeight)) {
instance.#com.mygwtapp.app.TablePage::scrolledToBottom()();
}
});
}-*/;
What could be wrong here?
The SimplePanel doesn't actually listen to ScrollEvent, if you want a panel with scroll support you can use ScrollPanel (which is a simple panel with scrolling support).
ScrollPanel scrollPanel = new ScrollPanel();
scrollPanel.addScrollHandler(new ScrollHandler() {
#Override
public void onScroll(ScrollEvent scrollEvent) {
// TODO - Does not trigger
Window.alert("Scroll");
}
});
In your second way, you're actually adding the event to the element itself, and waiting the event to fired from browser to call your handler. In both ways the event is fired from the browser, but the first one doesn't actually listen to it while the second one listens to it.

Override method that toggles 'isSelected' in getListCellRendererComponent

I would like to make my own method that controles when a component is 'isSelected'.
I have a JList containing multiple JPanel. The constructing class of the JPanel extends ListCellRenderer<>.
To show that one of the JList-component (the JPanels) is selected i use;
#Override
public Component getListCellRendererComponent(..., boolean isSelected, ...) {
if(isSelected){
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
return this;
}
I would like a method that keeps a selected item 'selected' eventhough I choose to select another. I understand this can be done by holding down CTRL, but .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); does not quite do the trick. I would rather like to select multiple by clicking on them, and deselect by clicking on them.
For this i have worked with the ListSelectionMode, but i cant find a way.
When done the above I would like to implement a method that only selects a component in the list when clicked in a certain area (instead of the whole component which is preset). I have made this method, which returns true if the correct area is clicked, else false. But since I cant figure out how to override the mouseevent that makes the components 'isSelected' this has been tricky.
Here is the code for the method I would like to override the 'isSelected' method;
this.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent evt) {
if(ActionHandler.mouseClickedPrebuild(evt.getPoint())){
//This code runs if that special place is clicked!
//So now the component should be 'isSelected' or
//deselected if it already was 'isSelected'.
}
}
});
This code is in the constructor of my JList
And the mouseClickedPrebuild method;
public static boolean mouseClickedPrebuild(Point point) {
int index = theJList.locationToIndex(point);
Rectangle bounds = theJList.getCellBounds(index,index);
Point p = bounds.getLocation();
return ( ... long list of greater than & less than ...);
//This gives the certain area which is accepted to return true
I solved the issue!
So I get my view showing by running this line;
// UI Class JScrollPane Custom JList
UIConstructor.listview.setViewportView(new ListView( -insert ArrayList here- ));
Here is my ListView. The custom DefaultListSelectionModel I used to solve my problem was posted by #FuryComptuers right here;
JList - deselect when clicking an already selected item
I had to make a few changes to the code, since the two methods in the selectionModel will run before my mouseevent. I saved the variabels staticly, so instead of running the code in setSelectionInterval I did it inside my mousePressed.
I then could add the boolean isSelected which returns true, if a curtain area within a specific list element is clicked.
public class ListViewd extends JList {
static boolean isSelected;
static Point point;
static boolean gS = false;
static int in0;
static int in1;
#Override
public Dimension getPreferredScrollableViewportSize() {
Dimension size = super.getPreferredScrollableViewportSize();
size.setSize(new Dimension(0,0));
return size;
}
public ListView(ArrayList<System> items) {
DefaultListModel<System> list = new DefaultListModel<System>();
for (System item : items) {
list.addElement(item);
}
this.setSelectionModel(new DefaultListSelectionModel() {
boolean gestureStarted = false;
#Override
public void setSelectionInterval(int index0, int index1) {
gS = gestureStarted;
in0 = index0;
in1 = index1;
gestureStarted = true;
}
#Override
public void setValueIsAdjusting(boolean isAdjusting) {
if (!isAdjusting) {
gestureStarted = false;
}
}
});
ListSelectionModel selectionModel = this.getSelectionModel();
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
point = e.getPoint();
isSelected = ActionHandler.mouseClickedPrebuild(point);
if(!gS && isSelected){
if (isSelectedIndex(in0)) {
selectionModel.removeSelectionInterval(in0, in1);
} else {
selectionModel.addSelectionInterval(in0, in1);
}
}
}
});
setModel(list);
setCellRenderer(new ListModelPrebuild());
}

Using a single EventHandler for entire array in Java

I've looked everywhere online and have been stumped for a few hours now. I have a program where I have an array of 40 imageViews on a screen. What I want to happen is when I click on a particular imageView in the array, I want the image to change within the imageView.
Here is what I have:
public void initBubbles(){
Image image = new Image("file:src/bubbles/images/bubble.png");
for (int i = 0; i < bubbles.length; i++) {
//Creates a new bubble
bubbles[i] = new Bubble(image, 'A', 1);
//Creates a new image view
ivs[i] = new ImageView(image);
//Various lines of codes that put the imageView in the scene..... (Not relevant)
ivs[i].addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent> () {
#Override
public void handle(MouseEvent event) {
System.out.println("Bubble Popped!");
ivs[i].setImage(new Image("popped.png":); //Will result in arrayOutOfBounds
}
});
}
}
The problem I am running into is getting the selected element from the MouseEvent. I understand that the line right after the "Bubble Popped!" message will cause an ArrayOutOfBounds exception. But I hope you understand what I am trying to. How can I get the imageView that was clicked based on the MouseEvent?
Any help is greatly appreciated as I've been stuck for a few hours.
I cannot check it in compiler now but based on the documentation I guess you will refer to the correct ImageView by the getTarget() method which MouseEvent inherits from javafx.event.Event.
So the correct code would be something like this:
#Override
public void handle(MouseEvent event) {
final ImageView iv = (ImageView) (event.getTarget());
iv.setImage(new Image("popped.png"));
}
And if you really wish to have a single EventHandler for entire array, you should define it outside of the for loop and assign it to a variable - otherwise you are creating a new instance of the handler for each ImageView.
public void initBubbles(){
final Image image = new Image("file:src/bubbles/images/bubble.png");
// Create an event handler to be re-used for all the ImageView's
final EventHandler eventHandler = new EventHandler<MouseEvent> () {
#Override
public void handle(MouseEvent event) {
final ImageView iv = (ImageView) (event.getTarget());
iv.setImage(new Image("popped.png"));
}
}
for (int i = 0; i < bubbles.length; i++) {
//Creates a new bubble
bubbles[i] = new Bubble(image, 'A', 1);
//Creates a new image view
ivs[i] = new ImageView(image);
// Register the event handler
ivs[i].addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
}
}
The handler code runs in different context than where you register the handler (addEventHandler()), so the value of i does not have the same meaning. You should consider the code of the handle() method as completely separate and independent on its surrounding code. The information of the "run-time context" of the handler is in the event which triggered the handler.
To use a parable, by calling the addEventHandler() you tell the ImageView this:
Dear ImageView, when a mouse event occurs above you, call the code of the handler.
And the handler:
Dear handler, when you are triggered, have a look at the target upon which you have been called, consider it as an instance of ImageView and set its image to something new.

My internal frames don't earn focus after opening... (Java)

I have a menu with items that open internal frames, but every time I need to click twice in the frame. One time to give focus to the Int.frame and the second time to actually do something (give focus to a textfield).
So, here is my question: It's possible to automatic give focus to the Int.Frame?
Code of my main screen:
public final class principal extends javax.swing.JFrame {
viewCity city = new viewCity();
public principal() {
initComponents();
myListeners();
setLocationRelativeTo(null);
}
public void myListeners() {
menuCity.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
menuCityClicked(e);
}
});
}
public void central(JInternalFrame window1) {
int lDesk = panelPrincipal.getWidth();
int aDesk = panelPrincipal.getHeight();
int lIFrame = window1.getWidth();
int aIFrame = window1.getHeight();
window1.setLocation(lDesk / 2 - lIFrame / 2, aDesk / 2 - aIFrame / 2);
}
private void menuCityClicked(MouseEvent e) {
if (!city.isVisible()) {
panelPrincipal.add(city);
central(city);
city.requestFocus(); // Nothing
city.requestFocusInWindow(); // Nothing
city.setVisible(true);
city.requestFocus(); // Nothing
city.requestFocusInWindow(); // Nothing
}
}}
No matter what, the menu will always keep the focus. For example, click in your browser's menu, and you will keep the focus, by moving the cursor you will open other menus without need to click.
By putting the properties "selection model" to null works, but give me nullpointerexception.
Ok, the problem is with the jMenu, but with jMenuItem Works fine, so... I'm using

How to release JScrollpane to make it be not always down to the bottom?

I added the following code segment to my project to force the JScrollPane automatically be down to the bottom after the user acting selection performance, however, when I tried to drag the scroll to go to the top, it still is forced to make the scroll down to the bottom, and I want to ask any solution to resolve it? Thanks in advance.
private void autoScrollToBottom() {
sdPanel.getTabScrollPane().getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
#Override
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}
});
}
try to use some boolean flag which will indicate if you should move your scrollbar. Set it to to true when you pereform a correct action then in your code:
#Override
public void adjustmentValueChanged(AdjustmentEvent e) {
if(isScrollingDownRequired) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
isScrollingDownRequired = false;
}
}

Categories

Resources