iText: button resize affects label - java

I'm trying to resize an existing PDF button. I want to amend the label from "Print" to "Print Amended".
PushbuttonField button = form.getNewPushbuttonFromField("HoldButton");
Rectangle box = button.getBox();
box.setRight(box.getRight() + 72); // Increase width by 1"
button.setBox(box);
button.setText("Print Amended");
form.replacePushbuttonField("HoldButton", button.getField());
The above code successfully changes the label, but not the size. The end result is a button with no change in width, and the label "Print Amended" squished together.
Is it possible to resize an existing button in iText?

I tried your example and I was surprised that I could reproduce your problem.
I looked into the iText code and I see that it is explicitly forbidden to change the /T value. This makes sense: if you want to replace an existing button, you don't want to change its name.
However, for some reason we also explicitly forbid changing the /Rect value. See the code of the AcroFields class:
for (Object element : button.getKeys()) {
PdfName key = (PdfName)element;
if (key.equals(PdfName.T) || key.equals(PdfName.RECT))
continue;
if (key.equals(PdfName.FF))
values.put(key, button.get(key));
else
widgets.put(key, button.get(key));
merged.put(key, button.get(key));
markUsed(values);
markUsed(widgets);
}
I am not sure why we made this decision when we wrote this code. If I remove || key.equals(PdfName.RECT), then your code works as expected.
As we deliberately excluded changing the dimensions of the button, I am in doubt if this is a bug or if we intentionally added that code there. Reading your requirement, I am inclined to remove || key.equals(PdfName.RECT) from the official source code.
PS: I know that this doesn't answer your question, but it does explain why your code doesn't work in spite of the fact that it looks perfectly OK. As I explained: I'm really surprised that it doesn't work, because I'm responsible for the iText code...
PS 2: I've changed the code in the official trunk.

Try something like:
newButton1 = new JButton("Print Amended") {
{
setSize(150, 75);
setMaximumSize(getSize());
}
};
or:
Try to use setMaximumSize() method
button.setMaximumSize(new Dimension(100,100));

Related

Combobox doesn't react to ".setValue()" nor ".select()"

This is my code:
comboBoxInstance.setInputPrompt("Something...");
comboBoxInstance.setNullSelectionAllowed(false);
Cookie comboCookie = getCookieByName("combo");
comboBoxInstance.select((comboCookie != null) ? comboCookie.getValue() : null);
final TextField textFieldInstance = new TextField("Textfield");
textFieldInstance.setInputPrompt("Something...");
Cookie tfCookie = getCookieByName("tf");
textFieldInstance.setValue((tfCookie != null) ? tfCookie.getValue() : null);
The problem is that the textfield works pretty well with the "Cookie setup". Only the combobox is refusing to work like it should.
The output is like this:
I've tried to use .setValue() instead of .select() but this has pretty much the same effect. I've also made sure that both the Cookie itself and the correct value are provided.
It may help to have a look at the part where the cookie is generated:
Cookie comboCookie = new Cookie("combo", comboBoxInstance.getValue().toString());
cookieProcessing(costcentreCookie); //<- sets maxage and vaadin related stuff (like adding the cookie)
Edit:
A few points to the data flow.
I'm generating a ComboBox with a SimpleJDBCConnectionPool's SQLContainer as the data container (coming from a TableQuery). Here's the initialization (executed in the constructor) in the combobox class:
private void init() throws SQLException {
this.setContainerDataSource(generateContainer());
this.setItemCaptionPropertyId("something");
}
The private method generateContainer() returns the SQLContainer of course.
This happens if I click on a particular button which opens up a dialog. This dialog is the fragment shown in the picture above. The combobox - of course - is part of it.
What one is supposed to do now is setting his data (get an item of the ComboBox) and hit save. The save button executes the routine to store the cookies. It's the code already mentioned above (Cookie comboCookie = new Cookie(...).
Okay, now the user is going to open up the dialog again. It's not important whether he reloads the application or just reopens the dialog (or does something else). It's basically the same in the app.
The dialog opens up and initializes the combobox (and the textfield) once again. However, this time it's supposed to gather the data out of the stored cookies. This is were the issue happens. This works well for the textfields (there are two but I've omitted one for shortening reasons) but not for the combobox, even tough it should've the exact same data as before. Hold in mind that it's the exact same class with the exact same initialization as when we stored the cookies in the first place.
I've the vague presumption, that it has to do something how the code is stacked. Maybe it hasn't finished loading the datacontainer while trying to set the appropriated value which then can't be found.
Edit2:
I've finally managed to reveal something. The ComboBox is indeed empty when the ".select()" is executed. However, this means, that the ComboBox is left untouched (it's only kind of "linked" to the datacontainer) until someone drops down the items. As soon as this happens, the items are there and I can possibly select them.
Is it supposed to work like this? O.o Am I able to fully initialize the combobox before I do something else? Something like:
private void init() throws SQLException {
this.setContainerDataSource(generateContainer());
this.setItemCaptionPropertyId("something");
this.gatherTheItems();
}
Edit3 - Test with ".setImmediate(true)"
I've changed the init to:
private void init() throws SQLException {
this.setContainerDataSource(generateContainer());
this.setItemCaptionPropertyId("SOMETHING");
this.setImmediate(true);
}
This didn't change anything. The combobox is still empty:
Finally! At first I've found a workaround which was like this:
for (Iterator it_IDS = combobox.getItemIds().iterator(); it_IDS.hasNext();) {
Object id = (Object) it_IDS.next();
if(id.toString().equals(cookie.getValue().toString())){
combo2.select(id);
break;
}
}
However, I couldn't believe that this was working since it doesn't change anything at the core problem. So I've investigated, that the RowID is built via a BigDecimal and voilà:
if(cookie != null) {
combobox.select(new RowId(new BigDecimal(cookie.getValue())));
}
I'm so happy right now :) Thanks for your patience kukis.
In case you came here because you're experiencing the same issue using a BeanItemContainer as datasource, bear in mind that you must implement both equals()and hashCode() methods on the underlying class for ComboBox's select() or setValue() methods to work.
You have plenty examples on Vaadin Forum on how to implement these methods:
ComboBox select value problem
Select or ComboBox does not Show Selected Property
Combobox select/setValue

How make the tkinter widget ".place()" method in python work similarly to the ".setbounds()" method in Java?

Python 3.4 and Eclipse IDE
I have a java form I am translating into python tkinter. I have a number of jlabels, jtextfields, jcomboboxes, and a seperator line that need to be placed on an identical python form with their respective python widget counterparts.
Example label from java using specific positioning:
JLabel lblWhichTrip = new JLabel("Which Trip:");
lblWhichTrip.setHorizontalAlignment(SwingConstants.RIGHT);
lblWhichTrip.setFont(new Font("Tahoma", Font.PLAIN, 16));
lblWhichTrip.setBounds(64, 22, 135, 20);
frmBookCalc.getContentPane().add(lblWhichTrip);
After 50 some odd browser tabs the python equivalent should be:
self.lblWhichTrip = Label(self, text = "Which Trip:", bg = "white", anchor = "e")
self.lblWhichTrip.place(x = 64, y = 22, height=135, width=20)
But the widget does not appear at all, not even in the wrong place.
The reason I want to use the ".place()" method in python is the same reason I used specific positioning in java, one has very little precise control over the ".pack()" method.
There was an instance where I found an example of the ".pack()" method being called directly before the ".place()" method, but more examples of just the ".place()" only used.
So here is the question:
How do I utilize the ".place()" method to similarly place the python tkinter widgets on the python form as I did with the Java form? I know I am close but it is not working.
With more work I have found the button below will put a button on my form but the labels section is blank as stated above.
languages = ['Python','Perl','C++','Java','Tcl/Tk']
labels = range(5)
for i in range(5):
ct = [random.randrange(256) for x in range(3)]
brightness = int(round(0.299*ct[0] + 0.587*ct[1] + 0.114*ct[2]))
ct_hex = "%02x%02x%02x" % tuple(ct)
bg_colour = '#' + "".join(ct_hex)
l = Label(self, text=languages[i], fg='White' if brightness < 120 else 'Black', bg=bg_colour)
l.place(x = 20, y = 30 + i*30, width=120, height=25)
self.QUIT = Button(self)
self.QUIT["text"] = "QUIT"
self.QUIT["fg"] = "red"
self.QUIT["command"] = self.quit
self.QUIT.pack({"side": "left"})
The form is being made in a class structure as denoted by the term "self". I have no idea why the button will show on the form but the labels will not. the only difference is ".pack()" and ".place()" methods used. From my research they are functionally the same thing, they just go about it in different ways.
I have looked at so many examples my eyes hurt. If someone could clear this up i would be forever thankful.
Reference:
Reference for tkinter
Update:
The ".place()" does not like being inside a class or I don't know how to instantiate it inside a class. I got it to work by neglecting the class structure that I wanted to use. How do I get ".place()" to work inside a class?
Update:
import tkinter as tk
import random
root = tk.Tk()
w = 465
h = 590
x = (root.winfo_screenwidth()/2) - (w/2)
y = (root.winfo_screenheight()/2) - (h/2)
root.minsize(width=w, height=h)
root.maxsize(width=w, height=h)
root.resizable(width=tk.FALSE, height=tk.FALSE)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
root.configure(background='white')
root.option_add("*font", "Tahoma 12")
root.title("Book Calc")
lblWhichTrip = tk.Label(root, text = "Which Trip:", bg = "white", anchor = "e")
lblWhichTrip.place(x=200, y=30, height=135, width=20)
root.mainloop()
I ditched the py file and the class containing all the form stuff for a single file with direct code and now the label is not visible again. The code immediately above is the entirety of my program at the moment. I hope I can figure this out soon.
Update:
The height and width needs to be on place and not the label. Above code modified.
lblWhichTrip = tk.Label(root, text = "Which Trip:", bg = "white", anchor = "e")
lblWhichTrip.place(x=200, y=30, height=135, width=20)
This works perfectly fine outside of a class structure, but it doesn't seem to work inside of a class. This is a half answer for my question above for placing a label or other widget in a specific location on a python form.
The other half the question is still unanswered being that this solution does not work inside of a class, which it should. If someone can shed some light on this, it would be great. Someone else will be wanting to write a much more robust program than I at this time so a better answer than this one is needed.
Thank you.
Update:
root = tk.Tk()
app = Application(root)
The above is when you create the class. Root needs to be sent directly.
def __init__(self, master):
self.parent = master
A pointer to root needs to be set a class var for persistence.
lblWhichTrip = tk.Label(root, text = "Which Trip:", bg = "white", anchor = "e")
lblWhichTrip.place(x=85, y=-35, height=135, width=100)
Then you can make all the widgets you want from inside a class, and all the layout engines will work fine. Pack, Place, and Grid will work perfectly.
Answered fully from due diligence.
Refernce:
Additional info here

JavaFX : After setting text in textArea, setting scroll to bottom in separate thread is not working

I created one JavaFX application where I'm updating log with one background process. So I'm setting log text in TextArea and setting scroll to bottom using logs.setScrollTop(Double.MAX_VALUE). but scrollbar is set to little bit up from the bottom.
I also tried TextFlow inside ScrollPan and setting scroll to bottom using logDisplay.setVvalue(1.0). It is also giving the same result.
Platform.runLater(() -> {
logs.setText([setting log text]);//TextArea logs
logs.setScrollTop(Double.MAX_VALUE));
});
//For TextFlow inside ScrollPane
Platform.runLater(() -> {
logs.setText([setting log text]);//Text logs
logDisplay.setVvalue(1.0);
});
I also tried to run code in separate thread like
new Thread() {
public void run(){
System.out.println("called set test");
logs.setText([setting log text]);//Text logs
logDisplay.setVvalue(1.0);
}
}.start();
But nothing is working :(
Can you help me what's wrong in this?
Thanks
--Edit--
Looks like the problem is because of threading issue. Scrollbar value is updating to the previous text value. Actually while retrieving scroll value it's not retrieving latest value but it's getting older value so scrollbar set to end of the previous message, not actual last line.
I don't know the actual problem of this issue, but I found an alternative solution.
I'm setting caret's position at end of text using length of text.
logs.setText(logText);
logs.positionCaret(logText.length());
It is working for me. :)

Itext checkbox is always checked

I am using Itext to create a pdf and I cannot get the checkbox to uncheck. Here is my code:
RadioCheckField bt = new RadioCheckField(writer, new Rectangle(300, 300, 400, 400),
"check1", "Yes");
bt.setCheckType(RadioCheckField.TYPE_CHECK);
bt.setBorderWidth(BaseField.BORDER_WIDTH_THICK);
bt.setBorderColor(BaseColor.BLACK);
bt.setBackgroundColor(BaseColor.WHITE);
bt.setChecked(false);
PdfFormField ck = bt.getCheckField();
writer.addAnnotation(ck);
You can see that the bt.setChecked(false) is in the code, but the checkbox is still checked. I looked at the docs and it seems to me that it is supposed to work this way. What do I not understand?
First this:
You've posted the same question on Nabble which is not a site endorsed by iText. See http://lowagie.com/nabble for more info.
As you were not subscribed to the official mailing-list, I had to manually approve your question. Now I see that you posted the same question here. Cross-posting is usually not appreciated in a community.
As for your question, I've answered it here: http://article.gmane.org/gmane.comp.java.lib.itext.general/65407
Bottom line: I made a Short, Self Contained, Correct (Compilable), Example based on your code and I executed it. I couldn't reproduce the problem you reported. Maybe there is no problem. Maybe there was a problem in a previous version of iText that has now been fixed.
I also read that you shipped your code with the text color set to white. I don't understand: that doesn't make sense! Your PDF will have an interactive field, but people will never be able to see whether or not it's checked...
If you don't care, if all you wanted is to show a checkbox, then using an interactive field is overkill. You should have used a check box character, for instance from the ZapfDingbats font.
If you're using the AGPL version of iText, please show me the URL where I can find your code (as you know, the AGPL requires code using AGPL software to be distributed as AGPL too).
Try the following way, for me it is working:
public void addRadioGroup() throws Exception{
if(!this.doc.isOpen()){
this.doc.open();
}
PdfFormField radioGroup = PdfFormField.createRadioButton(this.writer, false);
radioGroup.setFieldName("numbers");
for(int i=0;i<3;i++){
Rectangle rect = new Rectangle(130+(40*i), 430, 160+(40*i), 455);
this.addRadioButtonKid(radioGroup, rect,String.valueOf(i));
}
this.writer.addAnnotation(radioGroup);
}
private void addRadioButtonKid(PdfFormField radio, Rectangle rect, String onValue) throws Exception{
RadioCheckField bt = new RadioCheckField(this.writer, rect, null, onValue);
bt.setBorderWidth(BaseField.BORDER_WIDTH_THICK);
bt.setBorderColor(Color.BLACK);
bt.setBackgroundColor(Color.WHITE);
bt.setCheckType(RadioCheckField.TYPE_CROSS);
bt.setChecked(false);
PdfFormField ck = bt.getCheckField();
ck.setPlaceInPage(1);
radio.addKid(ck);
}
The only problem I had was that the default "check style" wasn't changed. A user reported this problem back in 2011 on the mailinglist in 2011. If you need another style patch iText for yourself or use the workaround described by Mark.
Update: After 2 years they seem to have fixed the problem in the latest iText version 5.4.3 (cp. the change of Michaël Demey)
try using a checkbox instead of a radiobutton since you only have one

Text Missing On Checkbox Component for Swing After Adding Action

I'm writing a simple Swing app. I tried adding a checkbox as listed below. Once I added the actionHandler loadPickers the name Foo disappeared from where it was sitting next to the right of chckbxNewCheckBox. I tried adding a call to setHideActionText(), but now nothing displays.
JCheckBox chckbxNewCheckBox = new JCheckBox("Foo");
chckbxNewCheckBox.setToolTipText("");
chckbxNewCheckBox.setName("");
chckbxNewCheckBox.setHideActionText(true);
chckbxNewCheckBox.setAction(loadPickers);
mainPanel.add(chckbxNewCheckBox, "flowy,cell 0 1");
If I change it to this it works properly. I see the text "Foo".
JCheckBox chckbxNewCheckBox = new JCheckBox("Foo");
chckbxNewCheckBox.setToolTipText("");
chckbxNewCheckBox.setName("");
chckbxNewCheckBox.setHideActionText(true);
chckbxNewCheckBox.setAction(loadPickers);
chckbxNewCheckBox.setText("Foo"); //THIS DOES NOT WORK IF IT COMES BEFORE SET ACTION
mainPanel.add(chckbxNewCheckBox, "flowy,cell 0 1");
I've included the action here for completeness. Why does it work this way? Am I missing something here? Currently I'm using the WindowBuilder plugin for Eclipse with the Mig layout system (which I really like). Unfortunately I haven't figure out if there's a way to make WindowBuilder use the .setText() method instead of using the constructor. Any help on what I'm doing wrong, any insight on why this behavior exists like this, or a good workaround for WindowBuilder would be great.
private class LoadPickers extends AbstractAction {
public LoadPickers() {
//putValue(NAME, "SwingAction_2");
putValue(SHORT_DESCRIPTION, "Some short description");
}
public void actionPerformed(ActionEvent e) {
}
}
As explained in the JavaDoc of AbstractButton.setAction:
Setting the Action results in immediately changing all the properties described in Swing Components Supporting Action. Subsequently, the button's properties are automatically updated as the Action's properties change.
So all the following properties can be impacted by setting an action:
enabled
toolTipText
actionCommand
mnemonic
text
displayedMnemonicIndex
icon (NA for JCheckBox)
accelerator (NA for JCheckBox)
selected

Categories

Resources