How hide items when print current page? - vaadin

I create my web project by Vaadin 7.3.6
When I want to print current page I use this:
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickListener;
private ClickListener printListener;
printListener = new ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
JavaScript.getCurrent().execute("print();");
}
};
As result it's print current page.
The page content from text and two buttons (Print, OK) on the bottom of page. Nice.
But I want to print only text. Without this 2 buttons.
I want to hide buttons ONLY when printing current page.
When return to page I want to see again this two buttons.
How I can do this?
P.S. I try this:
final Button okButton = new Button(MessageService.getMessage("ok"));
final Button printButton = new Button(MessageService.getMessage("print"));
printButton.setStyleName("small-top-margin");
final JavaScript js = JavaScript.getCurrent();
final UI ui = UI.getCurrent();
printButton.addClickListener(event -> {
logger.debug("click_print");
Thread thread = new Thread(() -> {
ui.access(() -> {
logger.debug("hide_all_buttons");
printButton.setVisible(false);
okButton.setVisible(false);
js.execute("print();");
});
try {
logger.debug("wating_n_seconds");
Thread.sleep(3000);
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
ui.access(() -> {
logger.debug("show_all_buttons");
printButton.setVisible(true);
okButton.setVisible(true);
});
});
thread.start();
}); // click listener
First click on printButton - nothing happened
Second click on printButton - print all buttons. It's not correct.

You can hide the button easily with button.setVisible(false). The true trick is to get the button back. One one is to do this in thread and have sufficient delay before switching the button back visible. Here is an example (Java 8 syntax to make it more compact) This works both with Vaadin 7 & 8.
final Button print = new Button("Print");
final UI ui = this; // or UI.getCurrent() or getUI() depending where you are
final JavaScript js = JavaScript.getCurrent();
print.addClickListener(event -> {
Thread t = new Thread(() -> {
ui.access(() -> {
print.setVisible(false);
js.execute("print();");
});
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ui.access(() -> print.setVisible(true));
});
t.start();
});
layout.addComponent(print);
Alternative approach is to use theming, I.e.
Button print = new Button("Print");
print.addStyleName("no-print");
And the following into your mytheme.scss file, before #mixin mytheme
#media print {
.no-print {
display:none;
}
}

Related

Can I bind the return to a condition?

I have the following problem:
My method opens a JDialog with a bunch of buttons (only one in example code). I want to click a button and thereby choose an ImageIcon for my method to return. But the Method does not wait for me to click a button. It opens the window and then returns an empty ImageIcon.
public class Kartenauswahl {
ImageIcon bandit;
public ImageIcon auswahlfenster() {
int bwidth = new Integer(150);
int bheight = new Integer(225);
bandit = new ImageIcon("cover/Bandit.jpe");
bandit.setImage(bandit.getImage().getScaledInstance(bwidth,bheight,Image.SCALE_DEFAULT));
final JDialog kartenwahl = new JDialog();
kartenwahl.setTitle("Kartenwahl");
kartenwahl.setSize(1500,1000);
kartenwahl.setVisible(true);
kartenwahl.setLayout(new FlowLayout());
ImageIcon returnicon= new ImageIcon();
final JButton b1 = new JButton(); //just to get the Icon out of the void loop
JButton B1 = new JButton(bandit); //this is going to be the button I want to click to choose the ImageIcon which is returned
B1.setContentAreaFilled(false);
B1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
b1.setIcon(bandit);
kartenwahl.dispose();
}
});
kartenwahl.add(B1);
returnicon = (ImageIcon) b1.getIcon();
return returnicon;
}
}
Question: can I bind the return statement to a condition? Like "only return after I clicked that Button B1"?
Hi sorry for the long wait. I have written an custom JDialog that should work for you.
public class CustomDialog extends JDialog {
JButton[] buttons;
ImageIcon selectedImageIcon;
public CustomDialog() {
setSize(500, 500);
setLayout(new GridLayout(4, 6));
ActionListener actionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
selectedImageIcon = ((ImageIcon) ((JButton) e.getSource()).getIcon());
dispose();
}
};
buttons = new JButton[24];
for(int i = 0; i < 24; i++) {
buttons[i] = new JButton(new ImageIcon("path_to_your_image_file"));
buttons[i].addActionListener(actionListener);
add(buttons[i]);
}
setVisible(true);
}
public ImageIcon getSelectedImageIcon() {
return selectedImageIcon;
}
}
The initial size is not that important the GridLayout is. you mentioned that you would need 24 buttons so I created an grid with 4 rows and 6 columns.
Then I create the buttons in a loop and adding the same Listener to set the selection icon with the icon of the pressed button. Afterwards I dispose the screen triggering an windowClosed event.
You could simply create this Dialog from your main class and wait for the response like so:
public class main {
public static void main(String[] args) {
CustomDialog customDialog = new CustomDialog();
customDialog.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
ImageIcon icon = customDialog.getSelectedImageIcon();
//do something with your icon
}
});
}
}
Don't forget to mark this answer as correct if it fixes your problem.
Have a good one!

Vaadin Grid ItemClickListener fails to register clicks on column with ImageRenderer

I have the following code which is supposed to show a clickable icon which opens a popup dialog reading out a lengthy note.
this.capacityCommentColumn = this.facilityGrid.addColumn(
p -> {
if (Strings.isNullOrEmpty(p.getCapacityComment())) {
return null;
} else {
return new ThemeResource("img/note.svg");
}
},
new ImageRenderer<>())
.setWidth(80)
.setCaption("Note");
this.facilityGrid.addItemClickListener(new ItemClickListener<MapQueryService.RowResult>() {
#Override
public void itemClick(Grid.ItemClick<MapQueryService.RowResult> event) {
if (event.getColumn() == capacityCommentColumn && !Strings.isNullOrEmpty(event.getItem().getCapacityComment())) {
final NoteWindow noteWindow = new NoteWindow();
noteWindow.txtDescription.setValue("test");
noteWindow.show();
}
}
});
The problem is the code does not respond to clicks on the actual image, only on the outside. You can see this below. Any idea if its possible to make the image clickable?
You need to add a click listener to the Renderer as well. For example:
Grid<Integer> grid = new Grid();
private void addIconColumn() {
ImageRenderer<Integer> renderer = new ImageRenderer<>();
renderer.addClickListener(e -> iconClicked(e.getItem())); // allow clicks on the image
Grid.Column<Integer, ThemeResource> iconColumn = grid.addColumn(i -> new ThemeResource("img/icon.svg"), renderer)
.setCaption("Icon");
grid.addItemClickListener(e -> { // allow clicks on the cell
if (iconColumn.equals(e.getColumn())) {
iconClicked(e.getItem());
}
});
}
private void iconClicked(Integer i) {
... your UI logic here ...
}
You can see a working example here: https://github.com/alejandro-du/community-answers/tree/master/click-image-in-grid

BackRequested is triggering more than once in UWP app

I have an app in which i mainly have a webview. i am having a problem. i have made the back button to goto previous webpage of webview it works fine and when it has no previous pages it quits with a MessageBox(Popup). The problem is when i navigate another page and press back it recursively triggers back button event and shows the MessageBox
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += (s, e) =>
{
e.Handled = true;
if (Web_view.CanGoBack)
{
Web_view.GoBack();
e.Handled = true;
}
else
{
quit();
e.Handled = true;
}
};
The above is code of my main page
private async void quit()
{
MessageDialog msg = new MessageDialog("Do you really want to quit?", "Quit");
msg.Commands.Add(new UICommand("Yes") { Id = 0 });
msg.Commands.Add(new UICommand("No") { Id = 1 });
var ans = await msg.ShowAsync();
if(ans.Id.Equals(0))
{
//System.Diagnostics.Debug.WriteLine("Exit");
App.Current.Exit();
}
}
this is the code of quit function.
I am navigating to another page from this using code
private void about_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(BlankPage1));
}
And the backRequested code of blanckPage1 is
SystemNavigationManager.GetForCurrentView().BackRequested += (s,e)=>
{
e.Handled = true;
// Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested -= BlankPage1_BackRequested;
//System.Diagnostics.Debug.WriteLine("BackRequested");
if (Frame.CanGoBack)
{
e.Handled = true;
Frame.GoBack();
}
else
{
e.Handled = true;
}
};
To make it more clear for example when i open the app the webview navigates to www.example.com then following the links there i will get to some other page(for example www.example.com/link/firstlink). then i will navigate my frame to blankpage1 and from there i will press back. then insted of coming back to previous page (www.example.com/link/firstlink) it comes to beginning page (www.example.com) and shows the quit popup how can i fix this?
Thank you for all your replay.
Your problem is that you are still keeping the event handler: In your code when navigating back from BlankPage1, both .BackRequested handlers are called. You would need to deregister from .BackRequested on MainPage when leaving it, for example like this:
MainPage:
protected override void OnNavigatedTo(NavigationEventArgs e) {
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
}
protected override void OnNavigatedFrom(NavigationEventArgs e) {
SystemNavigationManager.GetForCurrentView().BackRequested -= OnBackRequested;
}
private void OnBackRequested(object sender, BackRequestedEventArgs e) {
// Your code to navigate back
if (Web_view.CanGoBack)
{
Web_view.GoBack();
e.Handled = true;
}
else
{
quit();
e.Handled = true;
}
}
And the same on BlankPage1... Though it would be far easier to register to BackRequested in your App.xaml.cs where you would handle your (Window.Current.Content as Frame) for the whole app, something like this. To make it "nice" code also with an interface:
INavigationPage:
public interface INavigationPage {
// When overriding the method returns true or false if the Page handled back request
bool HandleBackRequested();
}
App.xaml.cs:
// ... Code before
protected override void OnLaunched(LaunchActivatedEventArgs e) {
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
}
private void OnBackRequested(object sender, BackRequestedEventArgs e) {
Frame frame = Window.Current.Content as Frame;
if (frame == null) return;
INavigationPage page = frame.Content as INavigationPage;
if (page == null) return;
// Ask if the page handles the back request
if (page.HandleBackRequested()) {
e.Handled = true;
// If not, go back in frame
} else if (frame.CanGoBack) {
e.Handled = true;
frame.GoBack();
}
}
// ... Code after
MainPage.xaml.cs:
... class MainPage : Page, INavigationPage {
// ... Code before
// Implement the interface handling the backRequest here if possible
public bool HandleBackRequested() {
if (Web_view.CanGoBack) {
Web_view.GoBack();
return true;
}
return false;
}
// ... Code after
}
Then the BlankPage does not require any code and no subscribing to .BackRequested.

Capture Tab Click Event in Mono

I have a Tabhost in my app with 3 tabs. The tabs are all working fine.
Now I want to perform some additional logic when the tab is selected?.
For Example: In one of my tabs, I provide an option for the user to sort things in different order and update the another tab.
how can we get the click event of TabHost?
I have updated the Tab Creation (Activity) part.
Thanks in Advance.
[Activity(Label = "My Activity")]
public class TabSearch : TabActivity
{
protected override void OnCreate(Bundle bundle)
{
try
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Search_WOTab);
/* ******************** Adding 2 Tab Controls and setting Activity classes to Tabs added ******************** */
TabHost.TabSpec tspec;
Intent intent;
intent = new Intent(this, typeof(WOSearch));
intent.AddFlags(ActivityFlags.NewTask);
tspec = TabHost.NewTabSpec("Search");
tspec.SetIndicator("Search", Resources.GetDrawable(Resource.Drawable.Search));
tspec.SetContent(intent);
TabHost.AddTab(tspec);
intent = new Intent(this, typeof(WOFilter));
intent.AddFlags(ActivityFlags.NewTask);
tspec = TabHost.NewTabSpec("Filter");
tspec.SetIndicator("Filter", Resources.GetDrawable(Resource.Drawable.Filter));
tspec.SetContent(intent);
TabHost.AddTab(tspec);
TabHost.TabChanged += (sender, e) =>
{
Toast.MakeText(this, TabHost.CurrentTab.ToString(), ToastLength.Short).Show();
};
}
catch (Exception ex)
{
Toast.MakeText(this, ex.InnerException.ToString(), ToastLength.Short);
}
}
You can use the TabHost.TabChanged event.
tabHost.TabChanged += (sender, e) => {
if (tabHost.CurrentTab == 0) {
// Do what you want.
}
};
PS: Xamarin Docs is your friend.
Edit:
You should modify your code to this...
//TabHost.TabChanged += TabHost_TabChanged;
TabHost.TabChanged += (sender, e) =>
{
Toast.MakeText(this, TabHost.CurrentTab.ToString(), ToastLength.Short).Show();
};
TabHost.CurrentTab is the index of the selected tab.

how to creat a hyperlink url string in a Java MessageDialog?

a simple MessageDialog(or MessageBox,any method can open a dialog )like follows:
MessageDialog.openInformation(shell, "Test", "Get help form this link www.google.com");
is there any way to make www.google.com a hyperlink? click the url and open browser.
thats not possible out of the box. I created a class of my own, named MyMessageDialog to do this:
https://gist.github.com/andydunkel/8914008
Its basically all the source code from MessageDialog. Then I overwrote the createMessageArea method and added a Link instead of a label and added an event listener:
protected Control createMessageArea(Composite composite) {
// create composite
// create image
Image image = getImage();
if (image != null) {
imageLabel = new Label(composite, SWT.NULL);
image.setBackground(imageLabel.getBackground());
imageLabel.setImage(image);
//addAccessibleListeners(imageLabel, image);
GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.BEGINNING)
.applyTo(imageLabel);
}
// create message
if (message != null) {
linkLabel = new Link(composite, getMessageLabelStyle());
linkLabel.setText(message);
linkLabel.addSelectionListener(new SelectionAdapter(){
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("You have selected: "+e.text);
try {
// Open default external browser
PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(new URL(e.text));
}
catch (PartInitException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
catch (MalformedURLException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
}
});
GridDataFactory
.fillDefaults()
.align(SWT.FILL, SWT.BEGINNING)
.grab(true, false)
.hint(
convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH),
SWT.DEFAULT).applyTo(linkLabel);
}
return composite;
}
The MessageDialog can be called with HTML code in it now:
MyMessageDialog.openError(parent.getShell(), "Hehe", "Google.com Test");
Not a very optimal solution, but it works:
Andy

Resources