I am currently making a program for school where I have to lock the ratio while adjusting JSliders.
I could not figure out how to make one slider change with the same value while changing the first slider.
I want to change the sliders at a 1:1 ratio, so if I slide width up 5, the length will also go up 5, but I couldn't figure out how to find a constant difference to calculate when I change the value.
In your code you are setting length value based on length.getValue, but you want length to be set as width changes and vise versa. So I suggest that you set length like length.setValue(width.getValue());
if(lkRatio.isSelected() !=true){
tempw = width.getValue();
templ = length.getValue();
diff = width.getValue() - length.getValue();
}
if(lkRatio.isSelected()){
if(source == width){
length.setValue(width.getValue() - diff);
}
if(source == length){
width.setValue(length.getValue() + diff);
}
}
To answer "how can you create 2 sliders with same model" :
DefaultBoundedRangeModel brm = new DefaultBoundedRangeModel();
brm.setMaximum(100);
width = new JSlider(brm);
length = new JSlider(brm);
Related
I want to create a Card Deck app that contains (lets say) from 0 to 10 total cards as it runs.
I have a RelativeLayout created with XML inside a parent layout, this RelativeLayout has width to match parent and height to wrap content.
Now i want to add fixed size buttons (cards) to that layout and when the don't have room they must not deformate but be scaled and placed on top of the other.
When i just add them it happens this:https://postimg.org/image/ic8pmaju7/
But i want to achieve something like this :https://postimg.org/image/567dj49j9/
*For second image i used setmargins(xleft,x,x,x);...xleft++; , but when i have 2 or 5 buttons they keep being on the top of the other button, instead of just use the free space.
So im asking if there is a layout or a method that when there is no room (small screen or too many buttons) puts buttons on top and next of the other button than deforming them.
ConstraintLayout allows you to create large and complex layouts with a flat view hierarchy (no nested view groups). It's similar to RelativeLayout in that all views are laid out according to relationships between sibling views and the parent layout, but it's more flexible than RelativeLayout and easier to use with Android Studio's Layout Editor.
Using the ConstraintLayout you can do it, and spending less user processing than if you use nested LinearLayouts.
To put button next to button and adjust them in according to screen size, you can use the Chains, that is a resource of ConstraintLayout.
Chains provide group-like behavior in a single axis (horizontally or vertically). The other axis can be constrained independently.
Click here to read more about ConstraintLayout and Click here to read more about Chains.
Ok, guys i tryied what you suggested but i couldnt't achieve what i wanted, so i spent HOURS working on it and i ended up with some math and some help of fuctions to (at last) find the solution. I will post my code if someone wants to give a try:
public void ChangeView(View view) {
//here we put number of cards that we want to be scaled and displayed (cards=buttons)
int CardMax=13;//13 for example!!!
//getting scale for dpi of phone screen(i think??)
final float scale = getResources().getDisplayMetrics().density;
// getting some values we need to know
// **THESE VALUES DEPEND FROM SCREEN RESOLUTION OR THE SIZE OF BUTTON**
int layWidth = layout.getWidth(); //getting layout width that equals screen width(in pixels)
int btnWidth = (int) (50 * scale); //setting and scaling the width of the button for any screen
int maxLayfit=layWidth/btnWidth; //getting how many buttons can be added to layout without deformation
int layMidWidth = layWidth / 2; //getting layouts half width (that helps to start adding buttons from middle)
int StrMeasur; // this help how to start setting the buttons
if (CardMax <= maxLayfit) { // if cards are less than Layout can hold without deformation
StrMeasur = CardMax; // StrMeasur equals number of cards
} else {
StrMeasur = maxLayfit; // else equals max number of cards without deformation
}
int pointer=0; //pointer that will say where to put the first button
pointer = layMidWidth - ((btnWidth / 2) * StrMeasur);//depends of how many cards we have and button width
int start =layMidWidth-((btnWidth / 2) * StrMeasur);
int nextBtn = 0; //nextBtn says where to put the next button
//here we set the buttons on top and next to the previous button as we need **TRICKY PART**
if (CardMax > maxLayfit-1) { //if number of cards is bigger than the number the layout can hold
//then we calculate first card position (start/pointer) and the last card position(=layout width-button width)
//we find how many equal parts the layout has to be divided with the given cards
//and we get the width of the part to set it as pointer of the next card place
nextBtn =(((layWidth-start)-btnWidth)-start)/CardMax;
}else{
nextBtn=btnWidth; //else the pointer just set buttons next to the other
}
//Here we display all the buttons
for (int i = 0; i < CardMax; i++) {
Button cards = new Button(this);
cards.setWidth(btnWidth);
cards.setHeight((int) (90 * scale));
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params2.setMargins(pointer, 0, 0, 0);
cards.setLayoutParams(params2);
cards.setText("" + (i + 1));
cards.setId(i);
layout.addView(cards);
pointer = pointer + nextBtn;
}
}
I belive it will work on any screen.
Eclipse 3.6.2 has this bug documented here
https://bugs.eclipse.org/bugs/show_bug.cgi?id=358183
There are a couple of suggested workarounds. The first one did not work for me, but the second one did.
combo.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(final Event e) {
//We need the original text, not the displayed substring which would return methods such as combo.getText() or combo.getItem(combo.getSelectionIndex())
String text = combo.getItem((int) combo.getData("selectionIndex"));
//reset text limit
combo.setTextLimit(text.length());
GC gc = new GC(combo);
//exact dimensions of selected text
int textWidth = gc.stringExtent(text).x;
int magicConst = 14;
int comboWidth = combo.getClientArea().width - magicConst;
//In case the text is wider then the area on which it's displayed, we need to set a textLimit
if (textWidth > comboWidth) {
//find text limit - first we set it according to average char width of our text
int averageCharWidth = textWidth / text.length();
int tempLimit = comboWidth / averageCharWidth;
//sometimes on resize it can happen that computed tempLimit is greater than text length
if (tempLimit >= text.length()) {
tempLimit = text.length() - 1;
}
//then we fine-tune the limit - it must be as precise as possible
while (tempLimit > 0 && (comboWidth < gc.stringExtent(text.substring(0, tempLimit + 1)).x)) {
tempLimit--;
}
//textLimit must not be zero
if (tempLimit == 0) {
tempLimit++;
}
combo.setTextLimit(tempLimit);
}
combo.setText(text);
gc.dispose();
}
});
However, when I implement this, the widget thinks that user has changed some data (state change). This may be because of the call above to
combo.setText(text);
As our system is set up, there is a call to
org.eclipse.ui.forms.ManagedForm.isDirty()
which results in a prompt to the user to save the data every time user exits the form.
I am not familiar at all with SWT or jFace. Can anyone tell me
Is there any other way to get around the Eclipse 3.6 bug?
If not, is there a way for me to clear the dirty state of the Combo box so that the user is not prompted to save?
Thanks
Just setting the text of a Combo won't automatically set a ManagedForm to be dirty. So you must be adding a modify listener to the combo in order to do the set dirty.
You can remove the modify listener from the combo just before you do the setText and then add it back after the setText. This should stop the dirty flag from being set.
I have a JTextPane with content type "text/html". It is integrated in a JScrollPane.
The user can scroll down in this JTextPane and hits a button. At this moment I want to compute the topmost actual visible line of the JTextPane!
What I found in another post here where these lines:
public Integer getActualDisplayedRows() {
int y1 = jtextpane.getVisibleRect().y;
int lineHeight = jtextpane.getFontMetrics(jtextpane.getFont()).getHeight();
int topMostRow = (int) Math.ceil((double) y1 / lineHeight);
return topMostRow;
}
But this does not compute correct.. The number in lineHeight is too small. So, if I scroll to the 20th row -for example- the method returns more then 20..
I tried to set the height of the line via stylesheet (like here):
StyleSheet sh = editorKit.getStyleSheet();
sh.addRule("body {line-height: 50px}");
But doesn't matter what pixel number I set there, the resulting JTextPane has always the same height (and I am using the body tag)..
Do you have any suggestions??
Thank you very much for your help!
If I understand your requirement you just want to know the line number at the top of the viewport?
Here is some code for getting the line at the caret position:
public static int getLineAtCaret(JTextComponent component)
{
int caretPosition = component.getCaretPosition();
Element root = component.getDocument().getDefaultRootElement();
return root.getElementIndex( caretPosition ) + 1;
}
Don't know if this will work for HTML with all kinds of weird tags with images and tables etc. In this case I'm not sure what the meaning of "line" would be.
Now obviously the caret will not be at the top of the viewport, so you need to modify the logic to get an "offset" of the text at the top of the viewport.
So you should be able to use the viewToModel(...) method of the text pane. Something like:
int y = textPane.getVisibleRect().y;
Point p = new Point(5, y);
int offset = textPane.viewToModel( p );
I have a table in libgdx which is supposed to have 6 buttons, organised into 2 rows. Here's my code:
elementsTable.clear();
String[] colors = new String [6];
colors[0] = "red";
colors[1] = "orange";
colors[2] = "yellow";
colors[3] = "purple";
colors[4] = "blue";
colors[5] = "green";
String category = currentCategory.name();
category = category.substring(0, category.length()-1).toLowerCase(); //removes the last character because otherwise there would be an extra 's'
int count = 0;
for(String color : colors) {
ButtonStyle buttonStyle = new ButtonStyle();
buttonStyle.up = cellsSkin.getDrawable(category + "_" + color);
Button button = new Button(buttonStyle);
button.addListener(toolBoxListener);
button.setName(category + "_" + color);
button.setSize(toolBoxButtonSize, toolBoxButtonSize);
elementsTable.add(button).pad(toolBoxButtonPadding);
count ++;
if (count == Math.ceil((colors.length/2d))) elementsTable.row();
}
That's the filling. My buttons are of 6 different colors so I loop over the array with the color names to access the skin to get the drawable for the buttons. This part seems to work because when I debug and look at the table, it has the 6 buttons in there with the right size.
Then I set the position and size of my table and add it to the stage.:
elementsTable.setSize(toolBoxWidth, 500/(float)(3*toolBoxButtonSize+6*toolBoxButtonPadding)*elementsTable.getHeight());
elementsTable.setPosition(195, 30);
stage.addActor(elementsTable);
The stage has an orthographic camera set that should scale things down just fine.
However, what I get is this:
Another strange thin is that when I look at the table's height and width in debug mode, it says 0 even thoug there are elements in it that all have the corrct size.
Can anyone help me?
If you have any further questions on the problem, please ask! I tried to give a detailed description, but I am happy to answer your questions.
It seemsits just the position. 30 is too low for the Y:
elementsTable.setPosition(195, 30);
Try 150 for example:
elementsTable.setPosition(195, 150);
Remember the coordinate system that Libgdx (and OpenGL) use is with Y going up.
Suppose I have 2 text fields in a Java Swing file. I need to add a third field on top of the other two, then modify the alignment of the original two fields.
I am looking for some script or runtime classes which will dynamically change the alignment according to this requirement.
a1.setBounds(264,619+132,200,n);
a2.setBounds(264,641+132,200,n);
a3.setBounds(264,663+132,200,n);
If I want to add one field on top then I need to change all the below coordinates. So I need something like a script that will pass the X or Y coordinates value (suppose n) and the fields below will modify accordingly.
Note that I never user setBounds(...) since I always use a LayoutManager. However, I don't know your situation so I won't judge. Okay. maybe a little: USE A LAYOUT MANAGER!
Anyhoo, changing the magic numbers to something like this and you'll be able to add as many as you like w/o having to renumber everything.
[Untested, but you should get the idea]
const int yOffset = 22;
int yStart = 619;
int row = 0;
a1.setBounds(264, (yStart + (yOffset * row++)) + 132, 200, n);
a2.setBounds(264, (yStart + (yOffset * row++)) + 132, 200, n);
a3.setBounds(264, (yStart + (yOffset * row++)) + 132, 200, n);